# Buggy code
def pzmap(sys, plot=True, grid=False, title="Pole Zero Map", **kwargs):
    """
    Plot a pole/zero map for a linear system.

    Parameters
    ----------
    sys: LTI (StateSpace or TransferFunction)
        Linear system for which poles and zeros are computed.
    plot: bool, optional
        If ``True`` a graph is generated with Matplotlib,
        otherwise the poles and zeros are only computed and returned.
    grid: boolean (default = False)
        If True plot omega-damping grid.

    Returns
    -------
    pole: array
        The systems poles
    zeros: array
        The system's zeros.
    """
    # Check to see if legacy 'Plot' keyword was used
    if "Plot" in kwargs:
        import warnings

        warnings.warn(
            "'Plot' keyword is deprecated in pzmap; use 'plot'", FutureWarning
        )
        plot = kwargs["Plot"]

    # Get parameter values
    plot = config._get_param("rlocus", "plot", plot, True)
    grid = config._get_param("rlocus", "grid", grid, False)

    if not isinstance(sys, LTI):
        raise TypeError("Argument ``sys``: must be a linear system.")

    poles = sys.pole()
    zeros = sys.zero()

    if plot:
        import matplotlib.pyplot as plt

        if grid:
            if isdtime(sys, strict=True):
                ax, fig = zgrid()
            else:
                ax, fig = sgrid()
        else:
            ax, fig = nogrid()

        # Plot the locations of the poles and zeros
        if len(poles) > 0:
            ax.scatter(real(poles), imag(poles), s=50, marker="x", facecolors="k")
        if len(zeros) > 0:
            ax.scatter(
                real(zeros),
                imag(zeros),
                s=50,
                marker="o",
                facecolors="none",
                edgecolors="k",
            )

        plt.title(title)

    # Return locations of poles and zeros as a tuple
    return poles, zeros


# Traceback (AttributeError)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-7-4e6a52bd77da> in <module>
1 import control
2 g = control.tf(1, [1,1])
----> 3 control.pzmap(g, grid=True)

~/src/python-control/control/pzmap.py in pzmap(sys, plot, grid, title, **kwargs)
104                 ax, fig = zgrid()
105             else:
--> 106                 ax, fig = sgrid()
107         else:
108             ax, fig = nogrid()

~/src/python-control/control/grid.py in sgrid()
80     ax.axis[:].invert_ticklabel_direction()
81
---> 82     ax.axis["wnxneg"] = axis = ax.new_floating_axis(0, 180)
83     axis.set_ticklabel_direction("-")
84     axis.label.set_visible(False)

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/axislines.py in new_floating_axis(self, nth_coord, value, axis_direction)
571     def new_floating_axis(self, nth_coord, value, axis_direction="bottom"):
572         gh = self.get_grid_helper()
--> 573         axis = gh.new_floating_axis(nth_coord, value,
574                                     axis_direction=axis_direction,
575                                     axes=self)

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py in new_floating_axis(self, nth_coord, value, axes, axis_direction)
348             self, nth_coord, value, axis_direction)
349
--> 350         axisline = AxisArtist(axes, _helper)
351
352         # _helper = FloatingAxisArtistHelper(self, nth_coord,

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/axis_artist.py in __init__(self, axes, helper, offset, axis_direction, **kwargs)
744         self._axis_direction = axis_direction
745
--> 746         self._init_line()
747         self._init_ticks(**kwargs)
748         self._init_offsetText(axis_direction)

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/axis_artist.py in _init_line(self)
885         if axisline_style is None:
886             self.line = PathPatch(
--> 887                 self._axis_artist_helper.get_line(self.axes),
888                 color=rcParams['axes.edgecolor'],
889                 fill=False,

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py in get_line(self, axes)
268
269     def get_line(self, axes):
--> 270         self.update_lim(axes)
271         x, y = self.grid_info["line_xy"]
272

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py in update_lim(self, axes)
99
100     def update_lim(self, axes):
--> 101         self.grid_helper.update_lim(axes)
102
103         x1, x2 = axes.get_xlim()

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/axislines.py in update_lim(self, axes)
325
326         if self._force_update or self._old_limits != (x1, x2, y1, y2):
--> 327             self._update(x1, x2, y1, y2)
328             self._force_update = False
329             self._old_limits = (x1, x2, y1, y2)

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py in _update(self, x1, x2, y1, y2)
317         if self.valid() and self._old_values == (x1, x2, y1, y2):
318             return
--> 319         self._update_grid(x1, y1, x2, y2)
320         self._old_values = (x1, x2, y1, y2)
321         self._force_update = False

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/grid_helper_curvelinear.py in _update_grid(self, x1, y1, x2, y2)
365
366     def _update_grid(self, x1, y1, x2, y2):
--> 367         self.grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2)
368
369     def get_gridlines(self, which="major", axis="both"):

~/.miniconda3/envs/control-dev/lib/python3.8/site-packages/mpl_toolkits/axisartist/grid_finder.py in get_grid_info(self, x1, y1, x2, y2)
102         """
103
--> 104         extremes = self.extreme_finder(self.inv_transform_xy, x1, y1, x2, y2)
105
106         # min &amp; max rage of lat (or lon) for each grid line will be drawn.

~/src/python-control/control/grid.py in __call__(self, transform_xy, x1, y1, x2, y2)
42
43         lon_min, lon_max, lat_min, lat_max = \
---> 44             self._adjust_extremes(lon_min, lon_max, lat_min, lat_max)
45
46         return lon_min, lon_max, lat_min, lat_max

AttributeError: 'ModifiedExtremeFinderCycle' object has no attribute '_adjust_extremes'

# Fixed code
def pzmap(sys, plot=None, grid=None, title="Pole Zero Map", **kwargs):
    """
    Plot a pole/zero map for a linear system.

    Parameters
    ----------
    sys: LTI (StateSpace or TransferFunction)
        Linear system for which poles and zeros are computed.
    plot: bool, optional
        If ``True`` a graph is generated with Matplotlib,
        otherwise the poles and zeros are only computed and returned.
    grid: boolean (default = False)
        If True plot omega-damping grid.

    Returns
    -------
    pole: array
        The systems poles
    zeros: array
        The system's zeros.
    """
    # Check to see if legacy 'Plot' keyword was used
    if "Plot" in kwargs:
        import warnings

        warnings.warn(
            "'Plot' keyword is deprecated in pzmap; use 'plot'", FutureWarning
        )
        plot = kwargs["Plot"]

    # Get parameter values
    plot = config._get_param("pzmap", "plot", plot, True)
    grid = config._get_param("pzmap", "grid", grid, False)

    if not isinstance(sys, LTI):
        raise TypeError("Argument ``sys``: must be a linear system.")

    poles = sys.pole()
    zeros = sys.zero()

    if plot:
        import matplotlib.pyplot as plt

        if grid:
            if isdtime(sys, strict=True):
                ax, fig = zgrid()
            else:
                ax, fig = sgrid()
        else:
            ax, fig = nogrid()

        # Plot the locations of the poles and zeros
        if len(poles) > 0:
            ax.scatter(real(poles), imag(poles), s=50, marker="x", facecolors="k")
        if len(zeros) > 0:
            ax.scatter(
                real(zeros),
                imag(zeros),
                s=50,
                marker="o",
                facecolors="none",
                edgecolors="k",
            )

        plt.title(title)

    # Return locations of poles and zeros as a tuple
    return poles, zeros