pythonmatplotlibsubplot

How to create single column 3x1 plot in a 3x2 subplot?


I want to create a plot with 2 columns, with the 1st one has only 1 plot and the 2nd one has 3. I try to set it up by using the following code

import matplotlib.pyplot as plt

def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)

fig = plt.figure()
ax1 = plt.subplot(222)
ax2 = plt.subplot(224)
ax3 = plt.subplot(121)
axes = [ax1, ax2, ax3]
format_axes(fig)
plt.tight_layout()
plt.show()

But then I struggle to make 4th plot because subplot doesn't support index > 5, and I don't know how to make each plot figure size satisfies the given proportion.

I tried again using gridspec by using the code below

import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

def format_axes(fig):
    for i, ax in enumerate(fig.axes):
        ax.text(0.5, 0.5, "ax%d" % (i+1), va="center", ha="center")
        ax.tick_params(labelbottom=False, labelleft=False)

fig = plt.figure(layout="constrained")

gs = GridSpec(3, 2, figure=fig)
ax1 = fig.add_subplot(gs[: , 0])
ax2 = fig.add_subplot(gs[0, -1])
ax3 = fig.add_subplot(gs[1, 1])
ax4 = fig.add_subplot(gs[-1, 1])
format_axes(fig)

plt.show()

However, my problem arises again because I couldn't manipulate each plot's size.

Is there a universal way to make a column size plot for bigger nrows x ncols subplots? And could someone explain gridspec for me, I copied the code from matplotlib.org and changed some values.


Solution

  • Not sure which layout exactly you are trying to achieve, but if you're new to this I think that plt.subplot_mosaic might be easier, tweaking axes' sizes with height_ratios and widths_ratios.

    import matplotlib.pyplot as plt
    
    
    fig, axd = plt.subplot_mosaic(
        """
        AB
        AC
        AD
        """,
        constrained_layout=True,
        height_ratios=[1, 3, 2],
        width_ratios=[1, 2],
    )
    
    # axd is a dict of Axes, e.g. use axd["A"]
    
    def label_axes(axd):
        for ax_name, ax in axd.items():
            ax.text(0.5, 0.5, ax_name, va="center", ha="center")
            ax.tick_params(labelbottom=False, labelleft=False)
    
    label_axes(axd)
    
    fig.show()
    

    subplot mosaic layout