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

Jas*_*n S 8 python matplotlib

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

有没有办法使这成为默认值?出于某种原因,当按住字母键时,我的CPU不允许触摸板移动.我只希望平移/缩放x轴,而不是y轴.


编辑:在https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes.py#L3001找到平移/缩放功能

其中包含一个内部函数format_deltas.但是,当从FIG对象自动创建Axes对象时,我不知道如何用子类覆盖Axes类.

sim*_*onb 9

可以使用自己的轴类.在您的情况下,您可以继承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()
Run Code Online (Sandbox Code Playgroud)

对于缩放,您可能必须查看工具栏控件本身.该NavigationToolbar2类有drag_zoom这似乎是有什么与此有关的方法,但跟踪它是如何工作很快被事实,即不同的后端都有自己的版本(如复杂NavigationToolbar2TkAgg

编辑

可以在以下方面进行 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)
Run Code Online (Sandbox Code Playgroud)

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


Jas*_*n S 5

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
Run Code Online (Sandbox Code Playgroud)