根据不同子图的 y 轴更新 matplotlib 子图的 x 轴

Update the x-axis of a matplotlib subplot according to the y-axis of a different subplot

我想绘制这样的正交投影:

使用 matplotlib,可能包括 3D 子图。所有子图都应共享公共轴。

fig = plt.figure()
ax = fig.add_subplot(221, title="XZ")
bx = fig.add_subplot(222, title="YZ", sharey=ax)
cx = fig.add_subplot(223, title="XY", sharex=ax, sharey=[something like bx.Xaxis])
dx = fig.add_subplot(224, title="XYZ", projection="3d", sharex=ax, sharey=bx, sharez=[something like bx.Yaxis]

我不知道如何 "link" 一个图的 x 轴与另一个图的 y 轴。有办法实现吗?

派对迟到了但是...

您应该能够通过使用其他子图的轴数据手动更新一个子图的轴数据来完成您想要的。

例如,使用 post 中的符号,您可以将 cxylim 值与 bxxlim 值匹配,使用getset 方法。

cx.set_ylim(bx.get_ylim())

同样,您可以在子图中匹配刻度标签和位置。

bx_xticks = bx.get_xticks()
bx_xticklabels = [label.get_text() for label in bx.get_xticklabels()]
cx.set_yticks(bx_xticks)
cx.set_yticklabels(bx_xticklabels)

您应该能够以这种方式从已经实例化的子图中动态定义任何和所有轴属性和对象。

我通过利用事件处理程序解决了1 问题。 监听 "*lim_changed" 事件,然后正确地 get_*limset*_lim 同步限制就可以了。 请注意,您还必须反转右上图 YZ 中的 x 轴。

这是一个将 x 轴与 y 轴同步的示例函数:

def sync_x_with_y(self, axis):
    # check whether the axes orientation is not coherent
    if (axis.get_ylim()[0] > axis.get_ylim()[1]) != (self.get_xlim()[0] > self.get_xlim()[1]):
        self.set_xlim(axis.get_ylim()[::-1], emit=False)
    else:
        self.set_xlim(axis.get_ylim(), emit=False)

我实现了一个简单的 class Orthogonal Projection 可以很容易地制作这种图。

1 从大约一年前 Benjamin Root 在 matplotlib 邮件列表上给我的提示开始......很抱歉之前没有发布解决方案

这是我解决问题的方法,基本上是@elebards 答案的浓缩版。我只是将更新限制方法添加到轴 class,因此它们可以访问 set_xlim / set_ylim 方法。然后我将这些函数连接到我想要同步它的轴的回调。当这些被调用时,事件参数将被填充

import types
import matplotlib.pyplot as plt

def sync_y_with_x(self, event):
    self.set_xlim(event.get_ylim(), emit=False)

def sync_x_with_y(self, event):
    self.set_ylim(event.get_xlim(), emit=False)

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)

ax1.update_xlim = types.MethodType(sync_y_with_x, ax1)
ax2.update_ylim = types.MethodType(sync_x_with_y, ax2)

ax1.callbacks.connect("ylim_changed", ax2.update_ylim)
ax2.callbacks.connect("xlim_changed", ax1.update_xlim)