@@ -138,6 +138,13 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None, plotstr='b' if int(matplot
138138 f .canvas .mpl_connect (
139139 'button_release_event' ,partial (_RLClickDispatcher ,sys = sys , fig = f ,ax_rlocus = f .axes [1 ],plotstr = plotstr , sisotool = sisotool , bode_plot_params = kwargs ['bode_plot_params' ],tvect = kwargs ['tvect' ]))
140140
141+ # zoom update on xlim/ylim changed, only then data on new limits
142+ # is available, i.e., cannot combine with _RLClickDispatcher
143+ dpfun = partial (
144+ _RLZoomDispatcher , sys = sys , ax_rlocus = ax , plotstr = plotstr )
145+ ax .callbacks .connect ('xlim_changed' , dpfun )
146+ ax .callbacks .connect ('ylim_changed' , dpfun )
147+
141148 # plot open loop poles
142149 poles = array (denp .r )
143150 ax .plot (real (poles ), imag (poles ), 'x' )
@@ -427,23 +434,30 @@ def _RLSortRoots(mymat):
427434 prevrow = sorted [n , :]
428435 return sorted
429436
430- def _RLClickDispatcher (event ,sys ,fig , ax_rlocus ,plotstr , sisotool = False , bode_plot_params = None , tvect = None ):
431- """Rootlocus plot click dispatcher"""
437+ def _RLZoomDispatcher (event , sys , ax_rlocus , plotstr ):
438+ """Rootlocus plot zoom dispatcher"""
432439
433- # If zoom is used on the rootlocus plot smooth and update it
434- if plt .get_current_fig_manager ().toolbar .mode in ['zoom rect' ,'pan/zoom' ] and event .inaxes == ax_rlocus .axes :
435- (nump , denp ) = _systopoly1d (sys )
436- xlim ,ylim = ax_rlocus .get_xlim (),ax_rlocus .get_ylim ()
440+ nump , denp = _systopoly1d (sys )
441+ xlim , ylim = ax_rlocus .get_xlim (), ax_rlocus .get_ylim ()
442+
443+ kvect , mymat , xlim , ylim = _default_gains (
444+ nump , denp , xlim = None , ylim = None , zoom_xlim = xlim , zoom_ylim = ylim )
445+ _removeLine ('rootlocus' , ax_rlocus )
446+
447+ for i , col in enumerate (mymat .T ):
448+ ax_rlocus .plot (real (col ), imag (col ), plotstr , label = 'rootlocus' ,
449+ scalex = False , scaley = False )
437450
438- kvect , mymat , xlim , ylim = _default_gains ( nump , denp , xlim = None , ylim = None , zoom_xlim = xlim , zoom_ylim = ylim )
439- _removeLine ( 'rootlocus' , ax_rlocus )
451+ def _RLClickDispatcher ( event , sys , fig , ax_rlocus , plotstr , sisotool = False , bode_plot_params = None ,tvect = None ):
452+ """Rootlocus plot click dispatcher"""
440453
441- for i ,col in enumerate (mymat .T ):
442- ax_rlocus .plot (real (col ), imag (col ), plotstr ,label = 'rootlocus' )
454+ # Zoom is handled by specialized callback above, only do gain plot
455+ if event .inaxes == ax_rlocus .axes and \
456+ plt .get_current_fig_manager ().toolbar .mode not in \
457+ {'zoom rect' ,'pan/zoom' }:
443458
444- # if a point is clicked on the rootlocus plot visually emphasize it
445- else :
446- K = _RLFeedbackClicksPoint (event , sys , fig ,ax_rlocus ,sisotool )
459+ # if a point is clicked on the rootlocus plot visually emphasize it
460+ K = _RLFeedbackClicksPoint (event , sys , fig , ax_rlocus , sisotool )
447461 if sisotool and K is not None :
448462 _SisotoolUpdate (sys , fig , K , bode_plot_params , tvect )
449463
@@ -473,16 +487,16 @@ def _RLFeedbackClicksPoint(event,sys,fig,ax_rlocus,sisotool=False):
473487 K = float ('inf' )
474488 K_xlim = float ('inf' )
475489 K_ylim = float ('inf' )
476- print ('gain' ,K )
477- print ('x_tolerance:' ,x_tolerance )
478- print ('y_tolerance:' ,y_tolerance )
479- print ('gain_tolerance:' ,gain_tolerance )
480- print ('margin:' ,abs (K .imag / K .real ))
481- print ('Argument clickpoint' ,abs (K .imag / K .real ))
482- print ('Argument X_scale:' ,abs (K_xlim .imag / K_xlim .real ))
483- print ('Argument Y_scale:' ,abs (K_ylim .imag / K_ylim .real ))
490+ # print('gain',K)
491+ # print('x_tolerance:',x_tolerance)
492+ # print('y_tolerance:',y_tolerance)
493+ # print('gain_tolerance:',gain_tolerance)
494+ # print('margin:',abs(K.imag / K.real))
495+ # print('Argument clickpoint',abs(K.imag / K.real))
496+ # print('Argument X_scale:',abs(K_xlim.imag/K_xlim.real))
497+ # print('Argument Y_scale:',abs(K_ylim.imag/K_ylim.real))
484498 gain_tolerance += 0.1 * max ([abs (K_ylim .imag / K_ylim .real ),abs (K_xlim .imag / K_xlim .real )])
485- print ('New gain tolerance:' ,gain_tolerance )
499+ # print('New gain tolerance:',gain_tolerance)
486500
487501 if abs (K .real ) > 1e-8 and abs (K .imag / K .real ) < gain_tolerance and event .inaxes == ax_rlocus .axes and K .real > 0. :
488502
0 commit comments