【问题标题】:How to share the x axis in reverse between two subplots in matplotlib?如何在 matplotlib 中的两个子图之间反向共享 x 轴?
【发布时间】:2022-11-24 19:05:11
【问题描述】:

我想展示一个主题的两个不同解剖视图,正面和背面,我希望两者之间的坐标保持一致,同时还显示它们,就像您自然看到的那样。这意味着 X 轴应该在前视图中向右增加,在后视图中向左增加。

我希望导航操作(平移、缩放)同时影响两个视图。例如,如果我放大前视图中对象的左肩(位于图像的右侧),我希望后视图也放大左肩(位于图像的左侧)图片的一侧)。

通常这是通过与 sharexsharey 参数共享轴来实现的。然而,正如我所说,我希望第二个子图中的 X 轴(并且只有 X 轴)被反转,并且该选项强制两个子图中的限制以相同的方式进行。

有什么办法可以做到这一点?

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    您可以使用绘制数据的双 y 轴来促进这一点。这个双轴需要有与原始轴相反的 x 刻度

    from matplotlib import pyplot as plt
    
    x = [1, 2, 3, 4]
    y = [1, 2, 3, 4]
    
    f, ax = plt.subplots(1, 2, sharey=True, sharex=True,)
    
    
    # definel x, y, lims for inital axes
    ax[0].set_xlim(1, 4)
    ax[0].set_ylim(1, 4)
    
    # plot data on original axis
    ax[0].plot(x, y)
    
    # create twin axis with common y
    # and plot data on the twin with#
    # inverted x axis
    tx1 = ax[1].twiny()
    tx1.plot(x, y)
    tx1.set_xlim(4, 1)
    tx1.set_ylim(1, 4)
    
    # remove twin axes ticks
    tx1.set_xticks([])
    
    
    plt.show()
    

    缩放输出

    【讨论】:

    • 这就是我到现在为止一直在做的事情。这样做的问题是,如果我缩放其中一个轴,它不会对另一个轴产生影响,这就是我想要实现的目标。通常这是通过共享轴来实现的,但随后也会共享限制(以相同的顺序)。
    • 我已经更新了这个问题,希望能更好地解释我想要实现的目标。
    【解决方案2】:

    好吧,看起来似乎没有针对我要实现的目标已经实现的特定功能,所以经过一些修补之后,这是我能够想到的最简单的功能。

    我正在将它集成到 Qt 应用程序中,并且我已经修改了导航工具栏以隐藏一些操作并更改一些快捷方式。我最终做的是从我的自定义导航工具栏类中覆盖以下方法:

    class CustomNavigationToolbar(NavigationToolbar):
        ...
    
        def release_zoom(self, event) -> None:
            zoom_axes = self._zoom_info.axes[0]
            other_axes = [a for a in self.canvas.figure.get_axes() if a != zoom_axes][0]
            super().release_zoom(event)
            other_axes.set_ylim(zoom_axes.get_ylim())
            other_axes.set_xlim(reversed(zoom_axes.get_xlim()))
            self.canvas.draw_idle()
    
        def drag_pan(self, event) -> None:
            pan_axes = self._pan_info.axes[0]
            other_axes = [a for a in self.canvas.figure.get_axes() if a != pan_axes][0]
            super().drag_pan(event)
            other_axes.set_ylim(pan_axes.get_ylim())
            other_axes.set_xlim(reversed(pan_axes.get_xlim()))
            self.canvas.draw_idle()
    

    对于缩放操作,在释放鼠标按钮时更新视图(release_zoom 方法),因此我首先获取其他轴,在调用 super() 之后,我根据缩放轴更新 X 和 Y 限制.平移动作也是如此,但它会在拖动鼠标时更新(drag_pan 方法)。

    请注意,这适用于我的用例,因为我保证只有两个轴,但适应两个以上的轴并不困难。

    【讨论】:

      猜你喜欢
      • 2021-03-14
      • 2010-11-27
      • 2019-02-03
      • 2012-10-06
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多