python-3.x - 跨 gridspec 子图/轴共享 xlabel(部分行)
问题描述
我在三个子图中共享一个居中的 xlabel 时遇到一些间歇性问题,这些子图 1)仅跨越部分 gridspec 行和 2)其相对于彼此的宽度可能会有所不同。
使用文档我已经能够整理出我正在寻找的基本多图结构:
fig = plt.figure(figsize=(10,8), constrained_layout=True)
xlabel_234 = 'XLabel Thing2\n(to be centered under ax2, ax3, and ax4 with equal horiz. spacing btwn subplots)'
gs = fig.add_gridspec(nrows=14, ncols=1)
gs0 = gs[0:2]
gs1 = gs[2:].subgridspec(nrows=1, ncols=12)
ax1 = fig.add_subplot(gs0)
ax1.set_title('Something Short and Wide')
ax1.text(0.5, 0.5, 'ax1', ha='center')
ax1.set_xlabel('XLabel Thing1')
ax2 = fig.add_subplot(gs1[0, 0:1])
ax2.set_title('Something Tall\nand Narrow 2a')
ax2.text(0.5, 0.5, 'ax2', ha='center')
ax3 = fig.add_subplot(gs1[0, 1:6], sharey=ax2)
ax3.set_title('Something Tall\nand Narrow 2b')
ax3.text(0.5, 0.5, 'ax3', ha='center')
plt.setp(ax3.get_yticklabels(), visible=False)
ax3.set_xlabel(xlabel_234, x=0.7) # *x offset is a bit of hack*
ax4 = fig.add_subplot(gs1[0, 6:9], sharey=ax2)
ax4.set_title('Something Tall\n and Narrow 2c')
ax4.text(0.5, 0.5, 'ax4', ha='center')
plt.setp(ax4.get_yticklabels(), visible=False)
ax5 = fig.add_subplot(gs1[0, 9:12])
ax5.set_title('Something Tall\nand Narrow 3')
ax5.text(0.5, 0.5, 'ax5', ha='center')
ax5.set_xlabel('XLabel Thing3')
我想认出这篇文章来帮助我整理 y 轴共享。setp 中的可见性 kwarg 是一个巨大的帮助。
这篇文章帮助我(有点)获得了一个常见的 xlabel 居中,但它有点像 hack,并且可能会根据 ax2、ax3、ax4 的相对宽度产生一些奇怪的行为(影响间距)。而且我必须迭代地猜测 x 偏移值。
我有更精确的方法吗?而且,也许,标准化 xtick 标签格式(我知道如何一次性完成)。就像可能是 subgridspec-of-the-subgridspec?或者,其他文档显示“width_ratios”kwarg(尽管没有太多关于实施的信息)......这会是更好的方法吗(即子图间距可能不那么敏感)?其他?
干杯
解决方案
一些最近的功能(matplotlib 3.4.0+)可以在这里提供帮助:
subfigures
:具有自己的布局并且可以嵌套在其他(子)图形中的虚拟图形supxlabel
/supylabel
:(子)图形的公共轴标签
您可以使用它们以各种方式重现您的布局,但这里有一个示例供参考:
- 创建顶部/底部子图(顶部子图为
ax0
) - 在底部子图中,嵌套左/右子图(左子图为
ax1
-ax3
,右子图为ax4
) - 在左下角的子图中,使用自定义
gridspec
andsupxlabel
(forax1
-ax3
)
fig = plt.figure(constrained_layout=True, figsize=(10, 8))
# create top/bottom subfigs
(subfig_t, subfig_b) = fig.subfigures(2, 1, hspace=0.05, height_ratios=[1, 3])
# put ax0 in top subfig
ax0 = subfig_t.subplots()
ax0.set_title('ax0')
subfig_t.supxlabel('xlabel0')
# create left/right subfigs nested in bottom subfig
(subfig_bl, subfig_br) = subfig_b.subfigures(1, 2, wspace=0.1, width_ratios=[3, 1])
# put ax1-ax3 in gridspec of bottom-left subfig
gs = subfig_bl.add_gridspec(nrows=1, ncols=9)
ax1 = subfig_bl.add_subplot(gs[0, :1])
ax2 = subfig_bl.add_subplot(gs[0, 1:6], sharey=ax1)
ax3 = subfig_bl.add_subplot(gs[0, 6:], sharey=ax1)
ax1.set_title('ax1')
ax2.set_title('ax2')
ax3.set_title('ax3')
ax2.get_yaxis().set_visible(False)
ax3.get_yaxis().set_visible(False)
subfig_bl.supxlabel('xlabel1-3')
# put ax4 in bottom-right subfig
ax4 = subfig_br.subplots()
ax4.set_title('ax4')
subfig_br.supxlabel('xlabel4')
推荐阅读
- elasticsearch - Fluentd 错误:“缓冲区数据过多”
- bootstrap-4 - 在 bootstrap4 中创建电池符号
- css - WP输入框显示白色背景,即使我更改为“背景颜色:无;” (主题化建设者)
- javascript - 如何在javascript中一一处理数组?
- java - try-with-resource 与带有显式 close()-call 的普通代码
- sql-server - 是否可以将 MSSQL 中的表与基于同一表的视图合并?
- arrays - 打字稿和固定数组长度(array.slice)
- javascript - 通过使用 jQuery 检测页面上的所有数据,这个过程是如何完成的?
- python - 稍微修改继承的init方法时的最佳实践?
- model-view-controller - 如何在水晶报表上显示重复值