pythonmatplotlibcontourfmatplotlib-gridspec

How to create subplots using Gridspec


How can I produce 3x3 subplots where the first and second columns are filled contour and the third column will have two stacked horizontal line plots in each of the rows?

This is the kind of layout (not to scale) that I want. Any generic answer will be good(https://i.sstatic.net/D58zL.png)

The code below is an example but I want the line plots in the third column to be in different panels instead of an overplot.

 import numpy as np
 import matplotlib.pyplot as plt

 # Generate some random data for the contour plots
 x = np.linspace(-5, 5, 100)
 y = np.linspace(-5, 5, 100)
 X, Y = np.meshgrid(x, y)
 Z1 = np.exp(-(X ** 2 + Y ** 2) / 10)
 Z2 = np.exp(-((X - 1) ** 2 + (Y - 1) ** 2) / 10)

 # Create the figure and subplots
 fig, axes = plt.subplots(3, 3, figsize=(12, 9))

 # Plot filled contour in the first column
 axes[0, 0].contourf(X, Y, Z1)
 axes[1, 0].contourf(X, Y, Z2)
 axes[2, 0].contourf(X, Y, Z1 + Z2)

 # Plot filled contour in the second column
 axes[0, 1].contourf(X, Y, Z1)
 axes[1, 1].contourf(X, Y, Z2)
 axes[2, 1].contourf(X, Y, Z1 + Z2)

 # Generate some random data for the line plots
 x = np.linspace(0, 2 * np.pi, 100)
 y1 = np.sin(x)
 y2 = np.cos(x)
 y3 = np.tan(x)
 y4 = np.exp(-x)
 y5 = np.sqrt(x)
 y6 = x ** 2

 # Plot stacked line plots in the third column
 axes[0, 2].plot(x, y1)
 axes[1, 2].plot(x, y2)
 axes[2, 2].plot(x, y3)
 axes[0, 2].plot(x, y4)
 axes[1, 2].plot(x, y5)
 axes[2, 2].plot(x, y6)

 # Set titles and labels for subplots
 axes[0, 0].set_title('Contour 1')
 axes[0, 1].set_title('Contour 2')
 axes[0, 2].set_title('Line Plots')

 # Adjust the spacing between subplots
 plt.subplots_adjust(hspace=0.3, wspace=0.3)

 # Show the plot
 plt.show()

The line plot should have the same scale and also the contour plots.


Solution

  • You can use make_axes_locatable then append axis with append_axes.

    The codes for plotting lines :

    from mpl_toolkits.axes_grid1 import make_axes_locatable
    # Plot stacked line plots in the third column
    
    axes[0, 2].plot(x, y1)
    divider_0 = make_axes_locatable(axes[0, 2])
    cax0 = divider_0.append_axes("bottom", size="100%", pad=0.25, sharex=axes[0, 2])
    cax0.plot(x, y4)
    
    
    axes[1, 2].plot(x, y2)
    divider_1 = make_axes_locatable(axes[1, 2])
    cax1 = divider_1.append_axes("bottom", size="100%", pad=0.25, sharex=axes[1, 2])
    cax1.plot(x, y5)
    
    
    axes[2, 2].plot(x, y3)
    divider_2 = make_axes_locatable(axes[2, 2])
    cax2 = divider_2.append_axes("bottom", size="100%", pad=0.25, sharex=axes[2, 2])
    cax2.plot(x, y6)
    

    The output of the figure :

    enter image description here

    Update

    If you want to change the relative widths of the columns, you can use the argument width_ratios during the initialization of the figure:

    fig, axes = plt.subplots(3, 3, figsize=(12, 9), width_ratios=[1, 1, 2])
    

    The new output :

    enter image description here