@@ -171,22 +171,47 @@ def bode_plot(syslist, omega=None, dB=None, Hz=None, deg=None,
171171 #! TODO: Not current implemented; just use subplot for now
172172
173173 if (Plot ):
174+ # Set up the axes with labels so that multiple calls to
175+ # bode_plot will superimpose the data. This was implicit
176+ # before matplotlib 2.1, but changed after that (See
177+ # https://github.com/matplotlib/matplotlib/issues/9024).
178+ # The code below should work on all cases.
179+
180+ # Get the current figure
181+ fig = plt .gcf ()
182+ ax_mag = None
183+ ax_phase = None
184+
185+ # Get the current axes if they already exist
186+ for ax in fig .axes :
187+ if ax .get_label () == 'control-bode-magnitude' :
188+ ax_mag = ax
189+ elif ax .get_label () == 'control-bode-phase' :
190+ ax_phase = ax
191+
192+ # If no axes present, create them from scratch
193+ if ax_mag is None or ax_phase is None :
194+ plt .clf ()
195+ ax_mag = plt .subplot (211 , label = 'control-bode-magnitude' )
196+ ax_phase = plt .subplot (212 , label = 'control-bode-phase' ,
197+ sharex = ax_mag )
198+
174199 # Magnitude plot
175- ax_mag = plt .subplot (211 );
176200 if dB :
177- pltline = ax_mag .semilogx (omega_plot , 20 * np .log10 (mag ), * args , ** kwargs )
201+ pltline = ax_mag .semilogx (omega_plot , 20 * np .log10 (mag ),
202+ * args , ** kwargs )
178203 else :
179204 pltline = ax_mag .loglog (omega_plot , mag , * args , ** kwargs )
180205
181206 if nyquistfrq_plot :
182- ax_mag .axvline (nyquistfrq_plot , color = pltline [0 ].get_color ())
207+ ax_mag .axvline (nyquistfrq_plot ,
208+ color = pltline [0 ].get_color ())
183209
184210 # Add a grid to the plot + labeling
185211 ax_mag .grid (True , which = 'both' )
186212 ax_mag .set_ylabel ("Magnitude (dB)" if dB else "Magnitude" )
187213
188214 # Phase plot
189- ax_phase = plt .subplot (212 , sharex = ax_mag );
190215 if deg :
191216 phase_plot = phase * 180. / math .pi
192217 else :
@@ -353,28 +378,50 @@ def gangof4_plot(P, C, omega=None):
353378 L = P * C ;
354379 S = feedback (1 , L );
355380 T = L * S ;
356-
381+
382+ # Set up the axes with labels so that multiple calls to
383+ # gangof4_plot will superimpose the data. See details in bode_plot.
384+ plot_axes = {'t' : None , 's' : None , 'ps' : None , 'cs' : None }
385+ for ax in plt .gcf ().axes :
386+ label = ax .get_label ()
387+ if label .startswith ('control-gangof4-' ):
388+ key = label [len ('control-gangof4-' ):]
389+ if key not in plot_axes :
390+ raise RuntimeError ("unknown gangof4 axis type '{}'" .format (label ))
391+ plot_axes [key ] = ax
392+
393+ # if any of the axes are missing, start from scratch
394+ if any ((ax is None for ax in plot_axes .values ())):
395+ plt .clf ()
396+ plot_axes = {'t' : plt .subplot (221 ,label = 'control-gangof4-t' ),
397+ 'ps' : plt .subplot (222 ,label = 'control-gangof4-ps' ),
398+ 'cs' : plt .subplot (223 ,label = 'control-gangof4-cs' ),
399+ 's' : plt .subplot (224 ,label = 'control-gangof4-s' )}
400+
401+ #
357402 # Plot the four sensitivity functions
403+ #
404+
358405 #! TODO: Need to add in the mag = 1 lines
359406 mag_tmp , phase_tmp , omega = T .freqresp (omega );
360407 mag = np .squeeze (mag_tmp )
361408 phase = np .squeeze (phase_tmp )
362- plt . subplot ( 221 ); plt .loglog (omega , mag );
409+ plot_axes [ 't' ] .loglog (omega , mag );
363410
364411 mag_tmp , phase_tmp , omega = (P * S ).freqresp (omega );
365412 mag = np .squeeze (mag_tmp )
366413 phase = np .squeeze (phase_tmp )
367- plt . subplot ( 222 ); plt .loglog (omega , mag );
414+ plot_axes [ 'ps' ] .loglog (omega , mag );
368415
369416 mag_tmp , phase_tmp , omega = (C * S ).freqresp (omega );
370417 mag = np .squeeze (mag_tmp )
371418 phase = np .squeeze (phase_tmp )
372- plt . subplot ( 223 ); plt .loglog (omega , mag );
419+ plot_axes [ 'cs' ] .loglog (omega , mag );
373420
374421 mag_tmp , phase_tmp , omega = S .freqresp (omega );
375422 mag = np .squeeze (mag_tmp )
376423 phase = np .squeeze (phase_tmp )
377- plt . subplot ( 224 ); plt .loglog (omega , mag );
424+ plot_axes [ 's' ] .loglog (omega , mag );
378425
379426#
380427# Utility functions
0 commit comments