在matplotlib中仅为部分子图共享坐标轴

76 投票
4 回答
42546 浏览
提问于 2025-04-18 05:44

我有一个很大的图表,开始时是这样设置的:

import numpy as np
import matplotlib.pyplot as plt

fig, axs = plt.subplots(5, 4)

我想让第一列和第二列之间共享x轴,同时让第三列和第四列之间也共享x轴。不过,第一列和第二列的轴和第三列、第四列的轴是不一样的。

我在想有没有办法做到这一点,而不是在所有图表中都使用sharex=Truesharey=True

另外,这个教程也没太大帮助,因为它只讲了如何在每一行/列内部共享x/y轴;它们不能在不同的行/列之间共享轴(除非在所有轴之间共享)。

4 个回答

4

我在类似的情况下使用了 Axes.sharex 和 sharey。

https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.sharex.html#matplotlib.axes.Axes.sharex

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)

撰写回答