matplotlib强制平移/缩放以约束到x轴

时间:2013-05-23 03:59:16

标签: python matplotlib

Matplotlib有一项功能,如果您按住“x”或“y”键,它会限制平移或缩放到相应的轴。

有没有办法让它成为默认设置?由于某些原因,当按住字母键时,我的CPU不允许触摸板移动。我只希望平移/缩放x轴,而不是y轴。


编辑:在https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes.py#L3001

找到了平移/缩放功能

包含内部函数format_deltas。但是当从图对象自动创建Axes对象时,我不知道如何用子类覆盖Axes类。

2 个答案:

答案 0 :(得分:8)

可以使用您自己的轴类。在您的情况下,您可以继承matplotlib.axes.Axes并将drag_pan方法更改为始终表现为按下'x'键。但是,该类似乎没有定义缩放。以下内容仅允许x轴平移:

import matplotlib
import matplotlib.pyplot as plt    

class My_Axes(matplotlib.axes.Axes):
    name = "My_Axes"
    def drag_pan(self, button, key, x, y):
        matplotlib.axes.Axes.drag_pan(self, button, 'x', x, y) # pretend key=='x'

matplotlib.projections.register_projection(My_Axes)

figure = plt.figure()
ax = figure.add_subplot(111, projection="My_Axes")
ax.plot([0, 1, 2], [0, 1, 0])
plt.show()

对于缩放,您可能需要查看工具栏控件本身。 NavigationToolbar2类具有drag_zoom方法,这似乎与此相关,但跟踪其工作方式很快就会因为不同的后端都有自己的版本(例如{{3} }

修改

可以在以下位置对所需行为进行monkeypatch:

import types
def press_zoom(self, event):
    event.key='x'
    matplotlib.backends.backend_tkagg.NavigationToolbar2TkAgg.press_zoom(self,event)
figure.canvas.toolbar.press_zoom=types.MethodType(press_zoom, figure.canvas.toolbar)

你可以正确地做它并创建工具栏的子类,但是你必须创建Figure,FigureCanvas和NavigationToolbar的实例并将它们放在Tk应用程序或其他东西中。我不认为使用简单的绘图界面就可以使用自己的工具栏。

答案 1 :(得分:4)

simonb的方法有效,但我不得不针对press_zoom行为调整它,以便它使press_zoom方法成为类的一个特征,而不是实例,但我添加了一个钩子来修复每个实例的行为。

import types

def constrainXPanZoomBehavior(fig):
    # make sure all figures' toolbars of this class call a postPressZoomHandler()
    def overrideZoomMode(oldZoom, target):
        def newZoom(self, event):
            oldZoom(self, event)
            if hasattr(self, 'postPressZoomHandler'):
                self.postPressZoomHandler()
        return newZoom
    def overrideToolbarZoom(fig, methodname, functransform, *args):
        toolbar = fig.canvas.toolbar
        oldMethod = getattr(toolbar.__class__, methodname)
        newMethod = functransform(oldMethod, toolbar, *args)
        setattr(toolbar.__class__, methodname, newMethod)
    overrideToolbarZoom(fig, 'press_zoom', overrideZoomMode)

    # for this specific instance, override the zoom mode to 'x' always
    def postPressZoomHandler(self):
        self._zoom_mode = 'x'
    fig.canvas.toolbar.postPressZoomHandler = types.MethodType(postPressZoomHandler, fig.canvas.toolbar)
    return fig