2017-02-23 4 views
1

Ich nahm das Beispiel für eine slider widget, und versuchte, es in eine Klasse zu stecken. Die Schieber richtig funktionieren, aber aus irgendeinem Grunde die Taste und Radiobuttons reagieren nicht, wenn die Methode in einer Klasse ist:matplotlib.widgets Knopf funktioniert nicht innerhalb einer Klasse

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import Slider, Button, RadioButtons 
class test(object): 
    def __init__(self): 

     fig, ax = plt.subplots() 
     plt.subplots_adjust(left=0.25, bottom=0.25) 
     t = np.arange(0.0, 1.0, 0.001) 
     a0 = 5 
     f0 = 3 
     s = a0*np.sin(2*np.pi*f0*t) 
     l, = plt.plot(t, s, lw=2, color='red') 
     plt.axis([0, 1, -10, 10]) 

     axcolor = 'lightgoldenrodyellow' 
     axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor) 
     axamp = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor) 

     sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0) 
     samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0) 


     def update(val): 
      amp = samp.val 
      freq = sfreq.val 
      l.set_ydata(amp*np.sin(2*np.pi*freq*t)) 
      fig.canvas.draw_idle() 
     sfreq.on_changed(update) 
     samp.on_changed(update) 

     resetax = plt.axes([0.8, 0.025, 0.1, 0.04]) 
     button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975') 

     def reset(event): 
      sfreq.reset() 
      samp.reset() 
     button.on_clicked(reset) 

     rax = plt.axes([0.025, 0.5, 0.15, 0.15], facecolor=axcolor) 
     radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0) 


     def colorfunc(label): 
      l.set_color(label) 
      fig.canvas.draw_idle() 
     radio.on_clicked(colorfunc) 

     plt.show() 

Wenn ich versuche jetzt diese Klasse auf den Button zu verwenden und RadioButton- ist freezed..anyone diese angetroffen ?

Antwort

1

Sie verlieren den Verweis auf die Widgets und Methoden, die im Klassenkonstruktor statisch definiert sind. The documentation sagt "Um sicherzustellen, dass das Widget reaktionsfähig bleibt und nicht Müll gesammelt, sollte eine Referenz auf das Objekt vom Benutzer verwaltet werden."
Der übliche Weg, dies zu tun, ist die Verwendung von Klassenattributen (self.). Das bedeutet, dass Sie Ihren Code wie folgt ändern müssen:

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.widgets import Slider, Button, RadioButtons 
class test(object): 
    def __init__(self): 

     self.fig, ax = plt.subplots() 
     plt.subplots_adjust(left=0.25, bottom=0.25) 
     self.t = np.arange(0.0, 1.0, 0.001) 
     a0 = 5 
     f0 = 3 
     s = a0*np.sin(2*np.pi*f0*self.t) 
     self.l, = plt.plot(self.t, s, lw=2, color='red') 
     plt.axis([0, 1, -10, 10]) 

     axcolor = 'lightgoldenrodyellow' 
     axfreq = plt.axes([0.25, 0.1, 0.65, 0.03], facecolor=axcolor) 
     axamp = plt.axes([0.25, 0.15, 0.65, 0.03], facecolor=axcolor) 

     self.sfreq = Slider(axfreq, 'Freq', 0.1, 30.0, valinit=f0) 
     self.samp = Slider(axamp, 'Amp', 0.1, 10.0, valinit=a0) 
     self.sfreq.on_changed(self.update) 
     self.samp.on_changed(self.update) 

     resetax = plt.axes([0.8, 0.025, 0.1, 0.04]) 
     self.button = Button(resetax, 'Reset', color=axcolor, hovercolor='0.975') 
     self.button.on_clicked(self.reset) 

     rax = plt.axes([0.025, 0.5, 0.15, 0.15], facecolor=axcolor) 
     self.radio = RadioButtons(rax, ('red', 'blue', 'green'), active=0) 
     self.radio.on_clicked(self.colorfunc) 

     plt.show() 

    def update(self,val): 
     amp = self.samp.val 
     freq = self.sfreq.val 
     self.l.set_ydata(amp*np.sin(2*np.pi*freq*self.t)) 
     self.fig.canvas.draw_idle() 

    def reset(self, event): 
     self.sfreq.reset() 
     self.samp.reset() 

    def colorfunc(self, label): 
     self.l.set_color(label) 
     self.fig.canvas.draw_idle() 

test() 
Verwandte Themen