Matplotlib 外轴破坏子图布局
Matplotlib external axes ruin subplot layout
我想绘制一个包含 3 个子图的图形。中间的有 3 个不同的 x 轴,其中一个是分离的并放置在子图下方。当我使用 Gridspec
布局时,绘图区域等距间隔,但不同子图的轴标签之间的填充有很大不同:
这是重现该图的代码:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure(figsize=(3.375, 6.5))
gs0 = gridspec.GridSpec(3, 1, figure=fig)
ax0 = fig.add_subplot(gs0[0])
ax0.set_xlabel('x label 0')
ax1 = fig.add_subplot(gs0[1])
ax1.set_xlabel('x label 1a')
secax1 = ax1.twiny()
secax1.xaxis.set_ticks_position('bottom')
secax1.xaxis.set_label_position('bottom')
secax1.spines['bottom'].set_position(('outward', 40))
secax1.set_xlabel('x label 1b')
thax1 = ax1.twiny()
thax1.set_xlabel('x label 1c')
ax2 = fig.add_subplot(gs0[2])
ax2.set_xlabel('x label 2a')
ax2.set_ylabel('y label 2')
secax2 = ax2.twiny()
secax2.set_xlabel('x label 2b')
plt.tight_layout()
plt.savefig('3 subplots same size.png', dpi=300)
plt.show()
我正在寻找一种方法来使 complete 子图之间的间距相等,包括附加轴及其标签等所有内容。或者一种在网格内手动移动子图的方法。子图不需要保持相同的大小。
我尝试将 height_ratios
更改为
gs0 = gridspec.GridSpec(3, 1, figure=fig, height_ratios=[1, 1.5, 1])
但它不影响绘图之间的空间。
您可以使用 plt.subplots 并在实际绘图之间放置不可见的“间隙图”,然后您可以通过更改间隙图的 height_ratios 来调整间隙
f, (ax0, gap1, ax1, gap2, ax2) = plt.subplots(5, 1,figsize=(3.375,8), gridspec_kw={'height_ratios': [1,1,1,1.75,1]})
gap1.axis('off')# Make the gap plots invisable
gap2.axis('off')# Make the gap plots invisable
#ax0 = fig.add_subplot(gs0[0])
ax0.set_xlabel('x label 0')
#ax1 = fig.add_subplot(gs0[2])
ax1.set_xlabel('x label 1a')
secax1 = ax1.twiny()
secax1.xaxis.set_ticks_position('bottom')
secax1.xaxis.set_label_position('bottom')
secax1.spines['bottom'].set_position(('outward', 40))
secax1.set_xlabel('x label 1b')
thax1 = ax1.twiny()
thax1.set_xlabel('x label 1c')
#ax2 = fig.add_subplot(gs0[5])
ax2.set_xlabel('x label 2a')
ax2.set_ylabel('y label 2')
secax2 = ax2.twiny()
secax2.set_xlabel('x label 2b')
输出
这种事情是constrained_layout
比tight_layout
做得好的地方。 tight_layout
只允许一个边距大小,因此在子图行之间留出很多空间。 constrained_layout
gridspec 的每一行保留一个上下边距。
是的,constrained_layout 被标记为实验性的。这样它的行为就可以在没有警告的情况下被改变。但是 API 不太可能改变。
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig, (ax0, ax1, ax2) = plt.subplots(3,1, figsize=(3.375, 6.5),
constrained_layout=True)
ax0.set_xlabel('x label 0')
ax1.set_xlabel('x label 1a')
secax1 = ax1.twiny()
secax1.xaxis.set_ticks_position('bottom')
secax1.xaxis.set_label_position('bottom')
secax1.spines['bottom'].set_position(('outward', 40))
secax1.set_xlabel('x label 1b')
thax1 = ax1.twiny()
thax1.set_xlabel('x label 1c')
ax2.set_xlabel('x label 2a')
ax2.set_ylabel('y label 2')
secax2 = ax2.twiny()
secax2.set_xlabel('x label 2b')
我想绘制一个包含 3 个子图的图形。中间的有 3 个不同的 x 轴,其中一个是分离的并放置在子图下方。当我使用 Gridspec
布局时,绘图区域等距间隔,但不同子图的轴标签之间的填充有很大不同:
这是重现该图的代码:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure(figsize=(3.375, 6.5))
gs0 = gridspec.GridSpec(3, 1, figure=fig)
ax0 = fig.add_subplot(gs0[0])
ax0.set_xlabel('x label 0')
ax1 = fig.add_subplot(gs0[1])
ax1.set_xlabel('x label 1a')
secax1 = ax1.twiny()
secax1.xaxis.set_ticks_position('bottom')
secax1.xaxis.set_label_position('bottom')
secax1.spines['bottom'].set_position(('outward', 40))
secax1.set_xlabel('x label 1b')
thax1 = ax1.twiny()
thax1.set_xlabel('x label 1c')
ax2 = fig.add_subplot(gs0[2])
ax2.set_xlabel('x label 2a')
ax2.set_ylabel('y label 2')
secax2 = ax2.twiny()
secax2.set_xlabel('x label 2b')
plt.tight_layout()
plt.savefig('3 subplots same size.png', dpi=300)
plt.show()
我正在寻找一种方法来使 complete 子图之间的间距相等,包括附加轴及其标签等所有内容。或者一种在网格内手动移动子图的方法。子图不需要保持相同的大小。
我尝试将 height_ratios
更改为
gs0 = gridspec.GridSpec(3, 1, figure=fig, height_ratios=[1, 1.5, 1])
但它不影响绘图之间的空间。
您可以使用 plt.subplots 并在实际绘图之间放置不可见的“间隙图”,然后您可以通过更改间隙图的 height_ratios 来调整间隙
f, (ax0, gap1, ax1, gap2, ax2) = plt.subplots(5, 1,figsize=(3.375,8), gridspec_kw={'height_ratios': [1,1,1,1.75,1]})
gap1.axis('off')# Make the gap plots invisable
gap2.axis('off')# Make the gap plots invisable
#ax0 = fig.add_subplot(gs0[0])
ax0.set_xlabel('x label 0')
#ax1 = fig.add_subplot(gs0[2])
ax1.set_xlabel('x label 1a')
secax1 = ax1.twiny()
secax1.xaxis.set_ticks_position('bottom')
secax1.xaxis.set_label_position('bottom')
secax1.spines['bottom'].set_position(('outward', 40))
secax1.set_xlabel('x label 1b')
thax1 = ax1.twiny()
thax1.set_xlabel('x label 1c')
#ax2 = fig.add_subplot(gs0[5])
ax2.set_xlabel('x label 2a')
ax2.set_ylabel('y label 2')
secax2 = ax2.twiny()
secax2.set_xlabel('x label 2b')
输出
这种事情是constrained_layout
比tight_layout
做得好的地方。 tight_layout
只允许一个边距大小,因此在子图行之间留出很多空间。 constrained_layout
gridspec 的每一行保留一个上下边距。
是的,constrained_layout 被标记为实验性的。这样它的行为就可以在没有警告的情况下被改变。但是 API 不太可能改变。
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig, (ax0, ax1, ax2) = plt.subplots(3,1, figsize=(3.375, 6.5),
constrained_layout=True)
ax0.set_xlabel('x label 0')
ax1.set_xlabel('x label 1a')
secax1 = ax1.twiny()
secax1.xaxis.set_ticks_position('bottom')
secax1.xaxis.set_label_position('bottom')
secax1.spines['bottom'].set_position(('outward', 40))
secax1.set_xlabel('x label 1b')
thax1 = ax1.twiny()
thax1.set_xlabel('x label 1c')
ax2.set_xlabel('x label 2a')
ax2.set_ylabel('y label 2')
secax2 = ax2.twiny()
secax2.set_xlabel('x label 2b')