2013-02-15 13 views
10

क्या किसी को पता है कि 'होम', 'बैक' और 'फॉरवर्ड' बटन मैटप्लॉटिब आकृति से 'ईवेंट' कैसे प्राप्त करें?matplotlib होम/बैक/फॉरवर्ड इवेंट्स में हुकिंग

मैं घटनाओं की जरूरत है इस तरह के मेरी भूखंडों ठीक से व्यवहार जब उन बटन दबाया जाता है, यानी डिफ़ॉल्ट व्यवहार नहीं कर रहा है मैं यह क्या जरूरत है ऐसा करने के लिए है कि मेरे कार्यों में से कुछ कॉल करने के लिए

matplotlib मान लिया गया अंतर्निहित डाटासेट है निरंतर और यह सब कुछ करने की ज़रूरत है x/y धुरी सीमा को रीसेट करें और उन बटनों के लिए दोबारा दोहराएं - दुर्भाग्य से यह धारणा मेरे मामले के लिए असत्य है - मेरे पास डेटा स्टैक है जिसे धक्का दिया जाना चाहिए और पॉप बटन की आवश्यकता है क्योंकि उन बटन ईवेंट ट्रिगर किए गए हैं

उत्तर

14

Matplotlib 'होम', 'बैक' या 'फॉरवर्ड' बटन ईवेंट प्रदान नहीं करता है।

कॉलबैक जोड़ने के लिए जिसे 'होम', 'बैक' या 'फॉरवर्ड' बटन इवेंट के साथ बुलाया जाएगा, एक आम दृष्टिकोण मैटलप्लिब बैकएंड को उप-वर्ग करना है।
लेकिन मैं इस दृष्टिकोण के पक्ष में नहीं हूं। मुझे लगता है कि इसमें दो विपक्ष हैं:

  1. यदि आप विभिन्न बैकएंड का उपयोग करना चाहते हैं, तो आपको उनमें से प्रत्येक को उप-वर्ग करना होगा।
  2. matplotlib के बाहर अपना खुद का बैकएंड तैनात करना मामूली नहीं है। आपका बैकएंड एक मॉड्यूल होना चाहिए जो PythonPATH में होना चाहिए।

के बाद से matplotlib द्वारा प्रदान की बैकेंड में से कोई भी ओवरराइड करता है NavigationToolbar2 के home, back और forward तरीकों।मैं अधिक संक्षिप्त बंदर-पैच दृष्टिकोण पसंद करता हूं।
उदाहरण के लिए, आप अपनी खुद की विधि से NavigationToolbar2 के home को प्रतिस्थापित कर सकते हैं।

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

मुझे लगता है कि एक उत्तर स्वीकार करने से बकाया पुरस्कार नहीं मिलता है - थोड़ा गैर-सहज ज्ञान युक्त; खुशी है कि मैंने एक घंटे के अतिरिक्त रहने के लिए देखा, उम्मीद है कि इसे समझ गया है। सभी उच्च गुणवत्ता वाले उत्तरों के लिए बहुत धन्यवाद – bph

4

यदि आप एक्स या वाई अक्ष का आकार बदलते हैं तो आप कुछ फ़ंक्शन को कॉल करने से दूर हो सकते हैं, सबसे आसान हैक xlim_changed औरसे जुड़ना होगाआपकी अक्षों द्वारा उत्पन्न घटनाएं। उदाहरण के लिए:

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

इसके लिए कॉलबैक निष्पादित करता है जब भी आप जब आप (कम से कम WX और जीटीके बैकेंड के साथ) पैन या ज़ूम उपकरण का उपयोग करने के साथ ही आगे, पिछड़े या घर कुंजी मारा। हालांकि, यह अभी भी निष्पादित करता है जब matplotlib पहले से ही अक्षों के सामान्य rescaling किया है।

यदि आप वास्तव में उन बटन कॉलबैक तक सीधे पहुंच चाहते हैं तो मुझे एक आसान बैकएंड-स्वतंत्र तरीका नहीं दिखाई दे रहा है क्योंकि ईवेंट बैकएंड आप जिस बैकएंड का उपयोग कर रहे हैं उसके आधार पर अलग-अलग काम करेंगे। मुझे लगता है कि मूल दृष्टिकोण matplotlib.backends.backend_<name>.NavigationToolbar2<name> को उपclass करना होगा और forward, back और home विधियों को ओवरराइड करना होगा। आपको अभी भी यह पता लगाना होगा कि आप जिस विशिष्ट बैकएंड का उपयोग कर रहे हैं उसके आधार पर अपनी नई टूलबार कक्षा को कैसे शामिल किया जाए।

यदि आप कुछ कस्टम 'आगे/पिछड़े' नियंत्रण को कार्यान्वित करना चाहते हैं जिसमें धुरी सीमा निर्धारित करने के लिए कुछ भी नहीं है, तो आप शायद 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 का उपयोग करना आपके लिए कोई विकल्प नहीं है तो हम अन्य बैकएंड के लिए कुछ ऐसा करने का प्रयास कर सकते हैं।