pythonmatplotlib

matplotlib: share axes like in plt.subplots but using the mpl.Figure API


I know how to make subplots with shared axes using the pyplot API:

from matplotlib import pyplot as plt

(fig, axes) = plt.subplots(3, 1, sharex=True)

Figure with 3 panes and one set of x-axis labels

But I can't replicate this effect using the matplotlib.figure.Figure API. I'm doing approximately the following. (Warning: I can't isolate the code because it's embedded in a whole Qt GUI, and if I take it out, I can't get the figure to display at all.)

from matplotlib.figure import Figure

n_axes = 3
fig = Figure()
axes = [fig.add_subplot(n_axes, 1, n+1)
        for n in range(n_axes)]
for ax in axes[:-1]:
    ax.sharex(axes[-1])

The ax.sharex command seems to have no effect.

For what it's worth, I switched to the plt.subplots method and everything seems to be working fine, but this smells like a bug or deficiency in matplotlib.


Solution

  • The sharex function is working as intended. You can see this if you add some dummy data to your example. The x-axis of the individual subplots are not being hidden after setting the shared axis in the for-loop. You can do this manually by adding:

    ax.get_xaxis().set_visible(False)
    

    Here is the full code:

    from matplotlib.figure import Figure
    
    n_axes = 3
    fig = Figure()
    
    axes = [fig.add_subplot(n_axes, 1, n + 1) for n in range(n_axes)]
    for ax in axes[:-1]:
        ax.sharex(axes[-1])
        ax.get_xaxis().set_visible(False)
    

    I have also added some dummy data to visualize the result:

    import numpy as np
    from matplotlib.figure import Figure
    
    n_axes = 3
    fig = Figure()
    
    axes = [fig.add_subplot(n_axes, 1, n + 1) for n in range(n_axes)]
    for ax in axes[:-1]:
        ax.sharex(axes[-1])
        ax.get_xaxis().set_visible(False)
    
    x = np.linspace(0, 10, 10)
    data = [np.sin(x), np.cos(x), np.tan(x) / 10]
    for ax, y, start in zip(axes, data,range(len(data))):
        ax.plot(x[start:], y[start:])
    fig.savefig("df.png")
    

    3 subplots with dummy data, with skewed staring

    Hope this helps