2013-02-15 117 views
10

有谁知道如何“得到”的“家”,“回”和“前进”从matplotlib数字按钮事件?matplotlib挂钩

我需要的事件打电话给我的一些功能,例如,我的阴谋行为正确时,这些按钮被按下,即默认行为是没有做什么,我需要做的

Matplotlib假设基础数据集是常数和所有它需要做的是重新设置这些按钮的X/Y轴限制和重制 - 不幸的是这种假设是不正确的我的情况 - 我有一个需要被压入和弹出的按键事件被触发

数据栈

回答

14

Matplotlib不提供“家”,“后退”或“前进”按钮的事件。

要添加将使用'home','back'或'forward'按钮事件调用的回调,常用的方法是对matplotlib后端进行子类化。
但我不赞成这种做法。我认为它有两个缺点:

  1. 如果你想使用不同的后端,你必须继承它们的每一个。
  2. 在matplotlib之外部署您自己的后端并不重要。你的后端必须是一个必须在PYTHONPATH中的模块。

由于没有由matplotlib提供后端的覆盖NavigationToolbar2homebackforward方法。我更喜欢更简洁的猴子修补方法。
例如,您可以用您自己的方法替换NavigationToolbar2home

import matplotlib.pyplot as plt 
from matplotlib.backend_bases import NavigationToolbar2 

home = NavigationToolbar2.home 

def new_home(self, *args, **kwargs): 
    print 'new home' 
    home(self, *args, **kwargs) 

NavigationToolbar2.home = new_home 

fig = plt.figure() 
plt.text(0.35, 0.5, 'Hello world!', dict(size=30)) 
plt.show() 

我们甚至可以模仿matplotlib的mpl_connect风格。

import matplotlib.pyplot as plt 
from matplotlib.backend_bases import NavigationToolbar2, Event 

home = NavigationToolbar2.home 

def new_home(self, *args, **kwargs): 
    s = 'home_event' 
    event = Event(s, self) 
    event.foo = 100 
    self.canvas.callbacks.process(s, event) 
    home(self, *args, **kwargs) 

NavigationToolbar2.home = new_home 

def handle_home(evt): 
    print 'new home' 
    print evt.foo 

fig = plt.figure() 
fig.canvas.mpl_connect('home_event', handle_home) 
plt.text(0.35, 0.5, 'Hello world!', dict(size=30)) 
plt.show() 
+0

我看到接受答案并不构成授予赏金 - 有点不直观;很高兴我注意到有一小时可以腾出空间,希望nymk能够得到它。非常感谢所有高质量的答案 – bph 2013-03-05 12:05:56

4

如果你可以逃脱只是调用一些功能,无论何时X或Y轴被调整,最简单的黑客将结合xlim_changedylim_changed您的坐标轴生成的事件。例如:

def on_xlim_change(*args): 
      print "do your pushing and popping here..." 
    ax = gca() 
    ax.callbacks.connect('xlim_changed',on_xlim_change) 

每当你打向前,向后或HOME键以及当您使用平移或缩放工具(至少与WX和GTK后端)这个回调执行。但是,它仍然在matplotlib已经完成其通常的轴重新调整之后执行。

如果你真的想进入这些按钮直接回调然后我看不到一个简单的后端无关的方式,因为事件处理将工作不同,具体取决于哪个后端你使用。我认为基本的做法是将matplotlib.backends.backend_<name>.NavigationToolbar2<name>的子类别覆盖forward,backhome方法。您仍然必须根据您正在使用的特定后端来确定如何合并新的工具栏类。

如果您想要实现一些自定义的“向前/向后”控制,它与设置轴限制无关,那么最好使用widgets来代替。

5

我不知道这个问题的后端独立的解决方案。但是,当您使用Qt4Agg - 后端,你可以试试这个:

import matplotlib 
matplotlib.use("Qt4Agg") 
import pylab as p 

def home_callback(): 
    print "home called" 

def back_callback(): 
    print "back called" 

def forward_callback(): 
    print "forward called" 

p.ion() 
p.plot(p.random((10))) 

fm = p.get_current_fig_manager() 

fm.toolbar.actions()[0].triggered.connect(home_callback) 
fm.toolbar.actions()[1].triggered.connect(back_callback) 
fm.toolbar.actions()[2].triggered.connect(forward_callback) 

首先,我得到了目前的数字管理器,这样我可以访问它的工具栏。然后我可以将其他回调连接到它的动作。

如果使用QT4Agg作为后端是不是你的选择,我们可以尝试做其他后端类似的东西。