Python matplotlib:隐藏子地块并用其他子地块填充空间

Python matplotlib:隐藏子地块并用其他子地块填充空间,python,matplotlib,Python,Matplotlib,我有一个图,包含三个子图,它们是垂直排列的。单击图中的后,我希望第二个子图ax2被隐藏,其他图填充空间。再次点击图形应恢复原始绘图和布局 隐藏子批ax2不是问题,但是如何重新排列其他子批的位置 我尝试使用set\u position和set\u subplotspec方法创建一个新的GridSpec,但没有任何效果。我肯定我错过了一些东西,任何帮助都将不胜感激 这是我的代码: import matplotlib.pyplot as plt from matplotlib import grids

我有一个图,包含三个子图,它们是垂直排列的。单击图中的后,我希望第二个子图
ax2
被隐藏,其他图填充空间。再次点击图形应恢复原始绘图和布局

隐藏子批
ax2
不是问题,但是如何重新排列其他子批的位置

我尝试使用
set\u position
set\u subplotspec
方法创建一个新的
GridSpec
,但没有任何效果。我肯定我错过了一些东西,任何帮助都将不胜感激

这是我的代码:

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()

您可以创建一个新的
gridspec
实例,并使用该实例在第二个图形中创建一些虚拟图形(您可以在
plt.show
之前关闭该实例,这样您就不会真正看到它,我们只想从这里的轴获取一些位置)

通过存储来自该虚拟图形和原始图形的
ax1
ax3
的两个可能位置,您可以使用
ax.set_position()
toggle_ax2
功能中更改其余两个轴的位置

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)

# Store the original positions of ax1 and ax3
pos1_1 = ax1.get_position()
pos3_1 = ax3.get_position()

# Create a second gridspec for when ax2 is hidden. Keep 5:1 ratio
gs2 = gridspec.GridSpec(2, 1, height_ratios=[5, 1])
fig2 = plt.figure()
ax1_2 = fig2.add_subplot(gs2[0])
ax3_2 = fig2.add_subplot(gs2[1])

# Store the positions of ax1 and ax3 in the new gridspec
pos1_2 = ax1_2.get_position()
pos3_2 = ax3_2.get_position()

# Close the dummy figure2
plt.close(fig2)

visible = True

def toggle_ax2(event):
    global visible

    visible = not visible
    ax2.set_visible(visible)

    # Use the stored positions to switch between 
    # different arrangements of ax1 and ax3
    if visible:
        ax1.set_position(pos1_1)
        ax3.set_position(pos3_1)
    else:
        ax1.set_position(pos1_2)
        ax3.set_position(pos3_2)
    plt.draw()

fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
原始配置:

卸下ax2后:

您可以定义两个不同的
GridSpec
s。一个有3个子地块,另一个有2个子地块。根据中间轴的可见性,您可以更改其他两个轴的位置以符合第一个或第二个GridSpec。
(正如其他答案可能暗示的那样,不需要任何虚拟数字。)

左:原件;右:点击后


如果有五个轴,会发生什么情况?…是否需要为显示的1、2、3、4和5个轴使用不同的
gridspec
?为了让事情变得更复杂,其中一些轴必须比其他轴大…@Sardathrion这完全取决于你到底想做什么。只要有五个轴,但仍然只想切换其中一个,您仍然只需要两个GridSpec。但为了能够将它们全部切换,可以使用大量gridspec,以防所有可能的组合都应有不同的高度比。然而,我建议您使用一个gridspec并动态地操作它的属性。@Sardathrion抱歉,这不是我的意思。如果您有5个子地块,并且希望能够将它们全部切换,那么您仍然需要5个GridSpec,一个有5行,一个有4行等等。但是您可以动态更新
高度比
,为每个子地块生成可供选择的布局。对。我现在摸索着。非常感谢。☺
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()