Matplotlib set_position() 不适用于 constrained_layout 的子图
Matplotlob set_position() is not working with subplots with constrained_layout
我有一组 4 个子图,其中在第一个子图中指定了纵横比。我从 this Github thread(这真的很有帮助)了解到“sharex 只是意味着他们共享他们的 x 数据限制。”
我无法实施该线程上推荐的 get_position()
和 set_position()
,因此我尝试了一个简单的测试来获取 ax2
位置并将其设置为自身。为什么ax2移动了?我认为它不应该移动,这种行为是意外的。
这里的根本问题是,考虑到第一个子图中定义的方面的初始约束,我怎样才能让我的子图 x 轴“对齐”以使宽度相同。我不能只定义其他子图中的方面,因为它们使用不同的 y 轴。
使用Python 3.8
fig = plt.figure(figsize=(3, 5), constrained_layout=True)
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0], aspect=0.7)
ax2 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex=ax1, sharey=ax3)
pos2 = ax2.get_position().bounds
ax2.set_position(pos2)
这似乎是由于使用 constrained_layout
,而 matplotlib 声明为 "experimental"。但是,他们确实声明使用 set_position
将手动放置 Axes 对象而不受约束布局的影响:
A manual call to set_position
will set the axes so constrained_layout has no effect on it anymore.
您可以使用 fig.execute_constrained_layout()
来解决这个问题:
fig = plt.figure(figsize=(3, 5), constrained_layout=True)
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0], aspect=0.7)
ax2 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex=ax1, sharey=ax3)
fig.execute_constrained_layout()
pos2 = ax2.get_position().bounds
ax2.set_position(pos2)
如果您只想避免布局受限,可以尝试 tight_layout
。在获得职位之前进行此调用。
fig = plt.figure(figsize=(3, 5)) # constrained_layout is False by default
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0], aspect=0.7)
ax2 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex=ax1, sharey=ax3)
fig.tight_layout() # reconfigure layout before getting positions
pos2 = ax2.get_position().bounds
ax2.set_position(pos2)
我有一组 4 个子图,其中在第一个子图中指定了纵横比。我从 this Github thread(这真的很有帮助)了解到“sharex 只是意味着他们共享他们的 x 数据限制。”
我无法实施该线程上推荐的 get_position()
和 set_position()
,因此我尝试了一个简单的测试来获取 ax2
位置并将其设置为自身。为什么ax2移动了?我认为它不应该移动,这种行为是意外的。
这里的根本问题是,考虑到第一个子图中定义的方面的初始约束,我怎样才能让我的子图 x 轴“对齐”以使宽度相同。我不能只定义其他子图中的方面,因为它们使用不同的 y 轴。
使用Python 3.8
fig = plt.figure(figsize=(3, 5), constrained_layout=True)
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0], aspect=0.7)
ax2 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex=ax1, sharey=ax3)
pos2 = ax2.get_position().bounds
ax2.set_position(pos2)
这似乎是由于使用 constrained_layout
,而 matplotlib 声明为 "experimental"。但是,他们确实声明使用 set_position
将手动放置 Axes 对象而不受约束布局的影响:
A manual call to
set_position
will set the axes so constrained_layout has no effect on it anymore.
您可以使用 fig.execute_constrained_layout()
来解决这个问题:
fig = plt.figure(figsize=(3, 5), constrained_layout=True)
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0], aspect=0.7)
ax2 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex=ax1, sharey=ax3)
fig.execute_constrained_layout()
pos2 = ax2.get_position().bounds
ax2.set_position(pos2)
如果您只想避免布局受限,可以尝试 tight_layout
。在获得职位之前进行此调用。
fig = plt.figure(figsize=(3, 5)) # constrained_layout is False by default
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0], aspect=0.7)
ax2 = fig.add_subplot(gs[1, 0], sharex=ax1, sharey=ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex=ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex=ax1, sharey=ax3)
fig.tight_layout() # reconfigure layout before getting positions
pos2 = ax2.get_position().bounds
ax2.set_position(pos2)