Python 在Matplotlib中以交互方式调整图形大小并切换绘图可见性?

Python 在Matplotlib中以交互方式调整图形大小并切换绘图可见性?,python,matplotlib,plot,Python,Matplotlib,Plot,我想做的是: 以两个子地块开始图形(一个子地块叠在另一个子地块上) 按键盘上的“x”键:调整图形大小,并在右侧显示第三个绘图 再次按“x”键:将图形调整回原始大小,并隐藏第三个绘图(不为第三个绘图留出空间) 通过下面的示例代码,我了解到了这一点(matplotlib 3.1.2,MINGW64中的Python3,Windows 10): 正如gif所示,即使在开始状态下,右边也有一些空白(因为除了定义网格,我不知道如何更好地解决这个问题)。然后,当“地物”窗口扩展/调整大小时,它没有“精确

我想做的是:

  • 以两个子地块开始图形(一个子地块叠在另一个子地块上)
  • 按键盘上的“x”键:调整图形大小,并在右侧显示第三个绘图
  • 再次按“x”键:将图形调整回原始大小,并隐藏第三个绘图(不为第三个绘图留出空间)
通过下面的示例代码,我了解到了这一点(matplotlib 3.1.2,MINGW64中的Python3,Windows 10):

正如gif所示,即使在开始状态下,右边也有一些空白(因为除了定义网格,我不知道如何更好地解决这个问题)。然后,当“地物”窗口扩展/调整大小时,它没有“精确”调整大小,因此它适合第三个绘图

如何实现第三个绘图的切换,使其隐藏时,右侧没有多余的空白-显示时,图形正好延伸,使第三个绘图适合(包括边距)(编辑:并且现有/初始两个绘图的大小不改变)

守则:

#/usr/bin/env蟒蛇3
导入matplotlib
打印(“matplotlib.\uuuuuuuuuuu版本{}”。格式(matplotlib.\uuuuuuu版本)
将matplotlib.pyplot作为plt导入
将numpy作为np导入
默认大小英寸=(9,6)
showThird=False
def onpress(事件):
全局图、ax1、ax2、ax3、showThird
如果event.key='x':
showThird=不showThird
如果显示第三个:
图设置尺寸英寸(默认尺寸英寸[0]+3,默认尺寸英寸[1],正向=真)
plt.subplot_adjust(right=0.85)#在右侧留出一点空间
ax3.设置_可见(真)
ax3.将轴设置在()上
其他:
图设置尺寸英寸(默认尺寸英寸[0],默认尺寸英寸[1],正向=真)
plt.子批次调整(右=0.9)#默认值
ax3.设置_可见(错误)
ax3.设置轴为off()
图canvas.draw()
def main():
全局图,ax1,ax2,ax3
扩展数据=np.arange(0,101,1)#0到100,两者都包括在内
ydata1=np.sin(0.01*xdata*np.pi/2)
ydata2=10*np.sin(0.01*xdata*np.pi/4)
图=plt.图(figsize=默认尺寸英寸,dpi=120)
ax1=plt.subplot2grid((3,3)、(0,0),colspan=2,rowspan=2)
ax2=plt.subplot2grid((3,3)、(2,0),colspan=2,sharex=ax1)
ax3=plt.subplot2grid((3,3)、(0,2),rowspan=3)
ax3.设置_可见(错误)
ax3.设置轴为off()
ax1.绘图(扩展数据,ydata1,color=“红色”)
ax2.绘图(扩展数据,ydata2,color=“卡其色”)
图canvas.mpl\u connect('key\u press\u event',lambda event:onpress(event))
plt.show()
#入口点
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

下面是一个示例,它保留初始绘图的宽度,并尝试在添加右侧绘图后缩放图形大小;然而,由于边距是相对表达的,而且Supblot之间也有一个空间,所以主情节“移动”,我并不真正想要:

代码:

#/usr/bin/env蟒蛇3
导入matplotlib
打印(“matplotlib.\uuuuuuuuuuu版本{}”。格式(matplotlib.\uuuuuuu版本)
将matplotlib.pyplot作为plt导入
将matplotlib.gridspec导入为gridspec
将numpy作为np导入
默认大小英寸=(9,6)
showThird=False
def onpress(事件):
全局图、ax1、ax2、ax3、showThird、gs1、gs2、扩展数据、主绘图和宽度
如果event.key='x':
showThird=不showThird
如果显示第三个:
ax1.设置_位置(gs2[:-1,:-1]。获取_位置(图))
ax2.设置_位置(gs2[2,0:-1]。获取_位置(图))
如果“ax3”不在globals()中:
ax3=图add_子批次(gs2[:,2])
ax3.绘图(扩展数据,扩展数据,颜色=“绿色”)
ax3.设置_可见(真)
ax3.将轴设置在()上
ax3.设置_位置(gs2[:,2]。获取_位置(图))
print(vars(fig.subplotpars))#不变:{validate':True,'left':0.125,'right':0.9,'bottom':0.11,'top':0.88,'wspace':0.2,'hspace':0.2}
打印(ax1.get_position())#Bbox(x0=0.125,y0=0.3817647058823529,x1=0.6264705882352941,y1=0.88)
打印(ax2.get_position())#Bbox(x0=0.125,y0=0.1099999999,x1=0.6264705882352941,y1=0.3364705882352941)
打印(ax3.get_position())#Bbox(x0=0.67205882835294118,y0=0.1099999999,x1=0.900000000000001,y1=0.88)
main_plot_width_rel_third=ax1.get_position().x1-ax1.get_position().x0
宽度系数=主绘图宽度相关/主绘图宽度相关
新的\u宽度\u英寸=默认的\u大小\u英寸[0]*宽度系数
打印(主打印-宽度-相对第三,宽度因子,新宽度-英寸)-0.5014705882352941 1.545452 13.9090907
图设置尺寸英寸(新宽度英寸,默认尺寸英寸[1],正向=真)
其他:
ax3.设置_可见(错误)
ax3.设置轴为off()
ax1.设置_位置(gs1[:-1,:]获取_位置(图))
ax2.设置_位置(gs1[2,0:2]。获取_位置(图))
print(vars(fig.subplotpars))#不变:{validate':True,'left':0.125,'right':0.9,'bottom':0.11,'top':0.88,'wspace':0.2,'hspace':0.2}
打印(ax1.get_position())#Bbox(x0=0.125,y0=0.3817647058823529,x1=0.899999999,y1=0.88)
打印(ax2.get_position())#Bbox(x0=0.125,y0=0.1099999999999,x1=0.899999999999,y1=0.3364705882352941)
图设置尺寸英寸(默认尺寸英寸[0],默认尺寸英寸[1],正向=真)
图canvas.draw()
def main():
全局图、ax1、ax2、ax3、gs1、gs2、扩展数据、主绘图和宽度
扩展数据=np.arange(0,101,1)#0到100,两者都包括在内
ydata1=np.sin(0.01*xdata*np.pi/2)
ydata2=10*np.sin(0.01*xdata*3*np.pi/4)
# https://stackoverflow.com/questions/43937066/
图=plt.图(figsize=默认尺寸英寸,dpi=120)
gs1=gridspec.gridspec(3,2,figure=fig)#,高度比=[5,2,1],hspace=0.3
gs2=gridspec.gridspec(3,3,figure=fig)#,高度比=[5,3]
#指定数组元素范围而不是colspan-请参见:
# https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/gridspec_multicolumn.html
#请注意,例如,“第0列和第1列”被指定为“0:2”(或者,如果这是所有列,则仅为“:”)-1是“最后一个元素”
ax1=图add_子批次(gs1[:-1,:])
ax2=图添加子批次(gs1[2,0:2],共享
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

w,h = plt.rcParams["figure.figsize"]
# Define dimensions in inches (could also just put numbers here)
left = plt.rcParams["figure.subplot.left"] * w
right = (1 - plt.rcParams["figure.subplot.right"]) * w
wspace = plt.rcParams["figure.subplot.wspace"] * w

figw1, figh1 = (7,5)
ax1width = figw1 - left - right
ax2width = 3.5

#calculate remaining free parameter, the figure width of the enlarged figure
figh2 = figh1
figw2 = left + ax1width + wspace + ax2width + right

#calculate subplot parameters for both cases
subplotpars1 = dict(left = left/figw1, right=(left + ax1width + wspace + ax2width)/figw1,
                    wspace=wspace/(ax1width+ax2width), )
subplotpars2 = dict(left = left/figw2, right=(left + ax1width + wspace + ax2width)/figw2,
                    wspace=wspace/(ax1width+ax2width), )

# create GridSpec
gs = GridSpec(2,2, width_ratios=(ax1width, ax2width), **subplotpars1)
# Create figure with 3 axes
fig = plt.figure(figsize=(figw1, figh1))
ax1 = fig.add_subplot(gs[0,0])
ax2 = fig.add_subplot(gs[1,0])
ax3 = fig.add_subplot(gs[:,1])

ax1.plot([2,4], color="C0")
ax2.plot([0,11], color="C1")
ax3.plot([5,15], color="C2")


# Updating machinery
current_state = [0]
subplotspars = [subplotpars1, subplotpars2]
figsizes = [(figw1, figh1), (figw2, figh2)]

def key_press(evt):
    if evt.key == "x":
        current_state[0] = (current_state[0] + 1) % 2
        gs.update(**subplotspars[current_state[0]])
        fig.set_size_inches(figsizes[current_state[0]], forward=True)
        fig.canvas.draw_idle()

fig.canvas.mpl_connect("key_press_event", key_press)


plt.show()