在matplotlib中仅为部分子图共享坐标轴
我有一个很大的图表,开始时是这样设置的:
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(5, 4)
我想让第一列和第二列之间共享x轴,同时让第三列和第四列之间也共享x轴。不过,第一列和第二列的轴和第三列、第四列的轴是不一样的。
我在想有没有办法做到这一点,而不是在所有图表中都使用sharex=True
和sharey=True
。
另外,这个教程也没太大帮助,因为它只讲了如何在每一行/列内部共享x/y轴;它们不能在不同的行/列之间共享轴(除非在所有轴之间共享)。
4 个回答
4
我在类似的情况下使用了 Axes.sharex 和 sharey。
import matplotlib.pyplot as plt
fig, axd = plt.subplot_mosaic([list(range(3))] +[['A']*3, ['B']*3])
axd[0].plot([0,0.2])
axd['A'].plot([1,2,3])
axd['B'].plot([1,2,3,4,5])
axd['B'].sharex(axd['A'])
for i in [1,2]:
axd[i].sharey(axd[0])
plt.show()
19
你可以手动管理坐标轴的共享,使用一个叫做 Grouper
的对象。这个对象可以通过 ax._shared_axes['x']
和 ax._shared_axes['y']
来访问。例如,
import matplotlib.pyplot as plt
def set_share_axes(axs, target=None, sharex=False, sharey=False):
if target is None:
target = axs.flat[0]
# Manage share using grouper objects
for ax in axs.flat:
if sharex:
target._shared_axes['x'].join(target, ax)
if sharey:
target._shared_axes['y'].join(target, ax)
# Turn off x tick labels and offset text for all but the bottom row
if sharex and axs.ndim > 1:
for ax in axs[:-1,:].flat:
ax.xaxis.set_tick_params(which='both', labelbottom=False, labeltop=False)
ax.xaxis.offsetText.set_visible(False)
# Turn off y tick labels and offset text for all but the left most column
if sharey and axs.ndim > 1:
for ax in axs[:,1:].flat:
ax.yaxis.set_tick_params(which='both', labelleft=False, labelright=False)
ax.yaxis.offsetText.set_visible(False)
fig, axs = plt.subplots(5, 4)
set_share_axes(axs[:,:2], sharex=True)
set_share_axes(axs[:,2:], sharex=True)
如果你想调整子图之间的间距,可以参考 这个问题。
编辑:根据最新的 matplotlib API 更新修改了代码。感谢 @Jonvdrdo 的建议!
71
有一种稍微简单但功能有限的选项可以用来创建子图。这个限制是针对整行或整列的子图来说的。
举个例子,如果你想让所有子图共享一个y轴,但每一列的子图可以有自己的x轴,在一个3行2列的子图布局中,你可以这样设置:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(3, 2, sharey=True, sharex='col')
74
我不太确定你想从你的问题中得到什么。不过,当你在图形中添加子图时,你可以指定每个子图应该和哪个子图共享哪个坐标轴。
这可以通过以下方式实现:
import matplotlib.pylab as plt
fig = plt.figure()
ax1 = fig.add_subplot(5, 4, 1)
ax2 = fig.add_subplot(5, 4, 2, sharex = ax1)
ax3 = fig.add_subplot(5, 4, 3, sharex = ax1, sharey = ax1)