@@ -44,18 +44,34 @@ def __init__(self):
4444 self ._static_ax .plot (t , np .tan (t ), "." )
4545
4646 self ._dynamic_ax = dynamic_canvas .figure .subplots ()
47- t = np .linspace (0 , 10 , 101 )
4847 # Set up a Line2D.
49- self ._line , = self ._dynamic_ax .plot (t , np .sin (t + time .time ()))
50- self ._timer = dynamic_canvas .new_timer (50 )
51- self ._timer .add_callback (self ._update_canvas )
52- self ._timer .start ()
48+ self .xdata = np .linspace (0 , 10 , 101 )
49+ self ._update_ydata ()
50+ self ._line , = self ._dynamic_ax .plot (self .xdata , self .ydata )
51+ # The below two timers must be attributes of self, so that the garbage
52+ # collector won't clean them after we finish with __init__...
5353
54- def _update_canvas (self ):
55- t = np .linspace (0 , 10 , 101 )
54+ # The data retrieval may be fast as possible (Using QRunnable could be
55+ # even faster).
56+ self .data_timer = dynamic_canvas .new_timer (1 )
57+ self .data_timer .add_callback (self ._update_ydata )
58+ self .data_timer .start ()
59+ # Drawing at 50Hz should be fast enough for the GUI to feel smooth, and
60+ # not too fast for the GUI to be overloaded with events that need to be
61+ # processed while the GUI element is changed.
62+ self .drawing_timer = dynamic_canvas .new_timer (20 )
63+ self .drawing_timer .add_callback (self ._update_canvas )
64+ self .drawing_timer .start ()
65+
66+ def _update_ydata (self ):
5667 # Shift the sinusoid as a function of time.
57- self ._line .set_data (t , np .sin (t + time .time ()))
58- self ._line .figure .canvas .draw ()
68+ self .ydata = np .sin (self .xdata + time .time ())
69+
70+ def _update_canvas (self ):
71+ self ._line .set_data (self .xdata , self .ydata )
72+ # It should be safe to use the synchronous draw() method for most drawing
73+ # frequencies, but it is safer to use draw_idle().
74+ self ._line .figure .canvas .draw_idle ()
5975
6076
6177if __name__ == "__main__" :
0 commit comments