3636from scipy .integrate import odeint
3737
3838from . import config
39- from .ctrlplot import ControlPlot , _add_arrows_to_line2D , \
39+ from .ctrlplot import ControlPlot , _add_arrows_to_line2D , _get_color , \
4040 _process_ax_keyword , _update_plot_title
4141from .exception import ControlNotImplemented
4242from .nlsys import NonlinearIOSystem , find_eqpt , input_output_response
@@ -90,7 +90,7 @@ def phase_plane_plot(
9090 Parameters to pass to system. For an I/O system, `params` should be
9191 a dict of parameters and values. For a callable, `params` should be
9292 dict with key 'args' and value given by a tuple (passed to callable).
93- color : str
93+ color : matplotlib color spec, optional
9494 Plot all elements in the given color (use `plot_<fcn>={'color': c}`
9595 to set the color in one element of the phase plot.
9696 ax : matplotlib.axes.Axes, optional
@@ -103,7 +103,7 @@ def phase_plane_plot(
103103 cplt : :class:`ControlPlot` object
104104 Object containing the data that were plotted:
105105
106- * cplt.lines: list of list of :class:`matplotlib.artist.Artist`
106+ * cplt.lines: array of list of :class:`matplotlib.artist.Artist`
107107 objects:
108108
109109 - lines[0] = list of Line2D objects (streamlines, separatrices).
@@ -153,6 +153,7 @@ def phase_plane_plot(
153153
154154 # Create copy of kwargs for later checking to find unused arguments
155155 initial_kwargs = dict (kwargs )
156+ passed_kwargs = False
156157
157158 # Utility function to create keyword arguments
158159 def _create_kwargs (global_kwargs , local_kwargs , ** other_kwargs ):
@@ -163,7 +164,7 @@ def _create_kwargs(global_kwargs, local_kwargs, **other_kwargs):
163164 return new_kwargs
164165
165166 # Create list for storing outputs
166- out = [[], None , None ]
167+ out = np . array ( [[], None , None ], dtype = object )
167168
168169 # Plot out the main elements
169170 if plot_streamlines :
@@ -217,7 +218,6 @@ def _create_kwargs(global_kwargs, local_kwargs, **other_kwargs):
217218 if initial_kwargs :
218219 raise TypeError ("unrecognized keywords: " , str (initial_kwargs ))
219220
220- # TODO: update to common code pattern
221221 if user_ax is None :
222222 if title is None :
223223 title = f"Phase portrait for { sys .name } "
@@ -263,7 +263,7 @@ def vectorfield(
263263 Parameters to pass to system. For an I/O system, `params` should be
264264 a dict of parameters and values. For a callable, `params` should be
265265 dict with key 'args' and value given by a tuple (passed to callable).
266- color : str
266+ color : matplotlib color spec, optional
267267 Plot the vector field in the given color.
268268 ax : matplotlib.axes.Axes
269269 Use the given axes for the plot, otherwise use the current axes.
@@ -298,7 +298,7 @@ def vectorfield(
298298 xlim , ylim , maxlim = _set_axis_limits (ax , pointdata )
299299
300300 # Figure out the color to use
301- color = _get_color (kwargs , ax )
301+ color = _get_color (kwargs , ax = ax )
302302
303303 # Make sure all keyword arguments were processed
304304 if check_kwargs and kwargs :
@@ -396,7 +396,7 @@ def streamlines(
396396 xlim , ylim , maxlim = _set_axis_limits (ax , pointdata )
397397
398398 # Figure out the color to use
399- color = _get_color (kwargs , ax )
399+ color = _get_color (kwargs , ax = ax )
400400
401401 # Make sure all keyword arguments were processed
402402 if check_kwargs and kwargs :
@@ -424,12 +424,11 @@ def streamlines(
424424 # Plot the trajectory (if there is one)
425425 if traj .shape [1 ] > 1 :
426426 with plt .rc_context (rcParams ):
427- out .append (
428- ax .plot (traj [0 ], traj [1 ], color = color ))
427+ out += ax .plot (traj [0 ], traj [1 ], color = color )
429428
430429 # Add arrows to the lines at specified intervals
431430 _add_arrows_to_line2D (
432- ax , out [- 1 ][ 0 ] , arrow_pos , arrowstyle = arrow_style , dir = 1 )
431+ ax , out [- 1 ], arrow_pos , arrowstyle = arrow_style , dir = 1 )
433432 return out
434433
435434
@@ -592,7 +591,7 @@ def separatrices(
592591 xlim , ylim , maxlim = _set_axis_limits (ax , pointdata )
593592
594593 # Figure out the color to use for stable, unstable subspaces
595- color = _get_color (kwargs )
594+ color = _get_color (kwargs , ax = ax )
596595 match color :
597596 case None :
598597 stable_color = 'r'
@@ -924,23 +923,6 @@ def _parse_arrow_keywords(kwargs):
924923
925924
926925# TODO: move to ctrlplot?
927- def _get_color (kwargs , ax = None ):
928- if 'color' in kwargs :
929- return kwargs .pop ('color' )
930-
931- # If we were passed an axis, try to increment color from previous
932- color_cycle = plt .rcParams ['axes.prop_cycle' ].by_key ()['color' ]
933- if ax is not None :
934- color_offset = 0
935- if len (ax .lines ) > 0 :
936- last_color = ax .lines [- 1 ].get_color ()
937- if last_color in color_cycle :
938- color_offset = color_cycle .index (last_color ) + 1
939- return color_cycle [color_offset % len (color_cycle )]
940- else :
941- return None
942-
943-
944926def _create_trajectory (
945927 sys , revsys , timepts , X0 , params , dir , suppress_warnings = False ,
946928 gridtype = None , gridspec = None , xlim = None , ylim = None ):
0 commit comments