Why nyquist plots are not working in my jupyter notebook? (python)
Question:
I am trying to do the Nyquist plot of a function in python, in jupiter notebook.
When i try to use the function control.nyquist_plot, used to generate the plot, pyton gives me an error in one of the libraries files. It draws only a part of the nyquist diagram before this error happens.
I also tried to use the same code others were using, to be sure it is not a syntax error, but i get the same error with files that are working for other people.
this is my code:
import numpy as np
import matplotlib.pyplot as plt
import control
sys = control.tf([0, 0, 10], [1, 3, 2])
fig = plt.figure(figsize=(10, 5))
control.nyquist_plot(sys);
And this is the error i get:
ValueError Traceback (most recent call last)
Cell In[3], line 4
1 sys = control.tf([0, 0, 10], [1, 3, 2])
3 fig = plt.figure(figsize=(10, 5))
----> 4 control.nyquist_plot(sys);
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\control\freqplot.py:1024, in nyquist_plot(syslist, omega, plot, omega_limits, omega_num, label_freq, color, return_contour, warn_encirclements, warn_nyquist, **kwargs)
1022 x_scl = np.ma.masked_where(scale_mask, resp.real)
1023 y_scl = np.ma.masked_where(scale_mask, resp.imag)
-> 1024 plt.plot(
1025 x_scl * (1 + curve_offset), y_scl * (1 + curve_offset),
1026 primary_style[1], color=c, **kwargs)
1028 # Plot the primary curve (invisible) for setting arrows
1029 x, y = resp.real.copy(), resp.imag.copy()
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\pyplot.py:2785, in plot(scalex, scaley, data, *args, **kwargs)
2783 @_copy_docstring_and_deprecators(Axes.plot)
2784 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
-> 2785 return gca().plot(
2786 *args, scalex=scalex, scaley=scaley,
2787 **({"data": data} if data is not None else {}), **kwargs)
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\axes_axes.py:1690, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
1689 for line in lines:
-> 1690 self.add_line(line)
1691 if scalex:
1692 self._request_autoscale_view("x")
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\axes_base.py:2304, in _AxesBase.add_line(self, line)
2301 if line.get_clip_path() is None:
2302 line.set_clip_path(self.patch)
-> 2304 self._update_line_limits(line)
2305 if not line.get_label():
2306 line.set_label(f'_child{len(self._children)}')
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\axes_base.py:2327, in _AxesBase._update_line_limits(self, line)
2323 def _update_line_limits(self, line):
2324 """
2325 Figures out the data limit of the given line, updating self.dataLim.
2326 """
-> 2327 path = line.get_path()
2328 if path.vertices.size == 0:
2329 return
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\lines.py:1029, in Line2D.get_path(self)
1027 """Return the `~matplotlib.path.Path` associated with this line."""
1028 if self._invalidy or self._invalidx:
-> 1029 self.recache()
1030 return self._path
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\lines.py:681, in Line2D.recache(self, always)
679 self._x_filled = self._x.copy()
680 indices = np.arange(len(x))
--> 681 self._x_filled[nanmask] = np.interp(
682 indices[nanmask], indices[~nanmask], self._x[~nanmask])
683 else:
684 self._x_filled = self._x
File <__array_function__ internals>:200, in interp(*args, **kwargs)
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\numpy\lib\function_base.py:1595, in interp(x, xp, fp, left, right, period)
1592 xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period))
1593 fp = np.concatenate((fp[-1:], fp, fp[0:1]))
-> 1595 return interp_func(x, xp, fp, left, right)
ValueError: array of sample points is empty
Answers:
I discovered the problem is a bug in the version 3.7.0 of matplotlib.
I installed the version 3.5.3 and now it works well.
To install this version for your jupyter notebook open your anaconda terminal and type:
conda install matplotlib=3.5.3
I am trying to do the Nyquist plot of a function in python, in jupiter notebook.
When i try to use the function control.nyquist_plot, used to generate the plot, pyton gives me an error in one of the libraries files. It draws only a part of the nyquist diagram before this error happens.
I also tried to use the same code others were using, to be sure it is not a syntax error, but i get the same error with files that are working for other people.
this is my code:
import numpy as np
import matplotlib.pyplot as plt
import control
sys = control.tf([0, 0, 10], [1, 3, 2])
fig = plt.figure(figsize=(10, 5))
control.nyquist_plot(sys);
And this is the error i get:
ValueError Traceback (most recent call last)
Cell In[3], line 4
1 sys = control.tf([0, 0, 10], [1, 3, 2])
3 fig = plt.figure(figsize=(10, 5))
----> 4 control.nyquist_plot(sys);
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\control\freqplot.py:1024, in nyquist_plot(syslist, omega, plot, omega_limits, omega_num, label_freq, color, return_contour, warn_encirclements, warn_nyquist, **kwargs)
1022 x_scl = np.ma.masked_where(scale_mask, resp.real)
1023 y_scl = np.ma.masked_where(scale_mask, resp.imag)
-> 1024 plt.plot(
1025 x_scl * (1 + curve_offset), y_scl * (1 + curve_offset),
1026 primary_style[1], color=c, **kwargs)
1028 # Plot the primary curve (invisible) for setting arrows
1029 x, y = resp.real.copy(), resp.imag.copy()
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\pyplot.py:2785, in plot(scalex, scaley, data, *args, **kwargs)
2783 @_copy_docstring_and_deprecators(Axes.plot)
2784 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
-> 2785 return gca().plot(
2786 *args, scalex=scalex, scaley=scaley,
2787 **({"data": data} if data is not None else {}), **kwargs)
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\axes_axes.py:1690, in Axes.plot(self, scalex, scaley, data, *args, **kwargs)
1688 lines = [*self._get_lines(*args, data=data, **kwargs)]
1689 for line in lines:
-> 1690 self.add_line(line)
1691 if scalex:
1692 self._request_autoscale_view("x")
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\axes_base.py:2304, in _AxesBase.add_line(self, line)
2301 if line.get_clip_path() is None:
2302 line.set_clip_path(self.patch)
-> 2304 self._update_line_limits(line)
2305 if not line.get_label():
2306 line.set_label(f'_child{len(self._children)}')
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\axes_base.py:2327, in _AxesBase._update_line_limits(self, line)
2323 def _update_line_limits(self, line):
2324 """
2325 Figures out the data limit of the given line, updating self.dataLim.
2326 """
-> 2327 path = line.get_path()
2328 if path.vertices.size == 0:
2329 return
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\lines.py:1029, in Line2D.get_path(self)
1027 """Return the `~matplotlib.path.Path` associated with this line."""
1028 if self._invalidy or self._invalidx:
-> 1029 self.recache()
1030 return self._path
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\matplotlib\lines.py:681, in Line2D.recache(self, always)
679 self._x_filled = self._x.copy()
680 indices = np.arange(len(x))
--> 681 self._x_filled[nanmask] = np.interp(
682 indices[nanmask], indices[~nanmask], self._x[~nanmask])
683 else:
684 self._x_filled = self._x
File <__array_function__ internals>:200, in interp(*args, **kwargs)
File ~.conda\envs\fondamenti-di-automatica\lib\site-packages\numpy\lib\function_base.py:1595, in interp(x, xp, fp, left, right, period)
1592 xp = np.concatenate((xp[-1:]-period, xp, xp[0:1]+period))
1593 fp = np.concatenate((fp[-1:], fp, fp[0:1]))
-> 1595 return interp_func(x, xp, fp, left, right)
ValueError: array of sample points is empty
I discovered the problem is a bug in the version 3.7.0 of matplotlib.
I installed the version 3.5.3 and now it works well.
To install this version for your jupyter notebook open your anaconda terminal and type:
conda install matplotlib=3.5.3