matplotlib: hide subplot and fill space with other subplots

matplotlib, python

Solution

You can define two different `GridSpec`s. One would have 3 subplots, the other 2. Depending on the visibility of the middle axes, you change the position of the other two axes to obey to the first or second GridSpec. (There is no need for any dummy figure or so, like other answers might suggest.)

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure()

gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1], hspace=0.3)
gs2 = gridspec.GridSpec(2,1, height_ratios=[5,3])

ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)

ax1.plot([1,2,3], [1,2,3], color="crimson")
ax2.plot([1,2,3], [2,3,1], color="darkorange")
ax3.plot([1,2,3], [3,2,1], color="limegreen")

visible = True

def toggle_ax2(event):
    global visible
    visible = not visible
    ax2.set_visible(visible)
    if visible:
        ax1.set_position(gs[0].get_position(fig))
        ax3.set_position(gs[2].get_position(fig))
    else:
        ax1.set_position(gs2[0].get_position(fig))
        ax3.set_position(gs2[1].get_position(fig))

    plt.draw()

fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()

Left: original; right: after clicking

Problem

I've got a figure that contains three subplots which are arranged vertically. Once I click into the figure, I want the second subplot `ax2` to be hidden and the other plots to fill the space. A second click into the figure should restore the original plot and layout. Hiding the subplot `ax2` isn't a problem, but how can I rearrange the positions of the other subplots? I've tried creating a new `GridSpec`, using the `set_position` and `set_subplotspec` methods, but nothing worked out. I'm sure I'm missing something here, any help would be appreciated. This is my code: ``` import matplotlib.pyplot as plt from matplotlib import gridspec fig = plt.figure() gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1]) ax1 = fig.add_subplot(gs[0]) ax2 = fig.add_subplot(gs[1], sharex=ax1) ax3 = fig.add_subplot(gs[2], sharex=ax2) visible = True def toggle_ax2(event): global visible visible = not visible ax2.set_visible(visible) plt.draw() fig.canvas.mpl_connect('button_press_event', toggle_ax2) plt.show() ```

Original source