1

假设我有一个带有 3 个图的图形画布... 2 个是使用 imshow 绘制的相同尺寸的图像,另一个是其他类型的子图。我希望能够链接 imshow 图的 x 轴和 y 轴,这样当我放大一个(使用 NavigationToolbar 提供的缩放工具)时,另一个缩放到相同的坐标,当我平移一个, 其他平底锅也是如此。

子图方法如 scatter 和 histogram 可以通过 kwargs 指定 sharex 和 sharey 的轴,但 imshow 没有这样的配置。

我开始通过继承 NavigationToolbar2WxAgg(如下所示)来解决这个问题......但这里有几个问题。1) 这将链接画布中所有绘图的轴,因为我所做的只是摆脱了对 a.in_axes() 的检查 2) 这对于平移效果很好,但是缩放会导致所有子图从同一个全局缩放点,而不是从它们各自轴上的同一点开始。

任何人都可以提出解决方法吗?

非常感谢!-亚当

from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg
class MyNavToolbar(NavigationToolbar2WxAgg):
    def __init__(self, canvas, cpfig):
        NavigationToolbar2WxAgg.__init__(self, canvas)

    # overrided
    # As mentioned in the code below, the only difference here from overridden
    # method is that this one doesn't check a.in_axes(event) when deciding which
    # axes to start the pan in...
    def press_pan(self, event):
        'the press mouse button in pan/zoom mode callback'

        if event.button == 1:
            self._button_pressed=1
        elif  event.button == 3:
            self._button_pressed=3
        else:
            self._button_pressed=None
            return

        x, y = event.x, event.y

        # push the current view to define home if stack is empty
        if self._views.empty(): self.push_current()

        self._xypress=[]
        for i, a in enumerate(self.canvas.figure.get_axes()):
            # only difference from overridden method is that this one doesn't
            # check a.in_axes(event)
            if x is not None and y is not None and a.get_navigate():
                a.start_pan(x, y, event.button)
                self._xypress.append((a, i))
                self.canvas.mpl_disconnect(self._idDrag)
                self._idDrag=self.canvas.mpl_connect('motion_notify_event', self.drag_pan)

    # overrided
    def press_zoom(self, event):
        'the press mouse button in zoom to rect mode callback'
        if event.button == 1:
            self._button_pressed=1
        elif  event.button == 3:
            self._button_pressed=3
        else:
            self._button_pressed=None
            return

        x, y = event.x, event.y

        # push the current view to define home if stack is empty
        if self._views.empty(): self.push_current()

        self._xypress=[]
        for i, a in enumerate(self.canvas.figure.get_axes()):
            # only difference from overridden method is that this one doesn't
            # check a.in_axes(event) 
            if x is not None and y is not None and a.get_navigate() and a.can_zoom():
                self._xypress.append(( x, y, a, i, a.viewLim.frozen(), a.transData.frozen()))

        self.press(event)
4

1 回答 1

3

我没有意识到 sharex 可以传递给 add_subplot ......

f = plt.figure()
ax1 = f.add_subplot(211)
ax2 = f.add_subplot(212, sharex=ax1, sharey=ax1)
ax1.imshow(np.random.randn(10,10), interpolation='nearest')
ax2.imshow(np.random.randn(10,10), interpolation='nearest')
f.canvas.draw()

但是,如果您尝试执行以下操作来设置轴对象以显示图像。

ax1.axis('image')

你会得到:

ValueError: adjustable must be "datalim" for shared axes

matplotlib 家伙告诉我我可以使用

ax1.set_adjustable("box-forced")
ax2.set_adjustable("box-forced")

相反,但它对我使用 matplotlib 版本 0.98.5.3 不起作用......我认为它适用于较新的版本。当我收到回复时会更新。

于 2010-05-27T19:19:51.440 回答