New plotting paradigm #645
Replies: 22 comments 58 replies
-
I like it very much. We can keep the The MATLAB wrappers could to the same without deprecation. |
Beta Was this translation helpful? Give feedback.
-
For reference, I found the old discussion we were having about this at the back end of #291. I think the main problems encountered back then are now fixed (e.g. functions |
Beta Was this translation helpful? Give feedback.
-
I also like this proposal quite a lot. We might think through what we want to do from time response and how this fits it. For example, the various time response functions ( Another thing to think about: what happens if you want to combine several plots, either in an array (a la |
Beta Was this translation helpful? Give feedback.
-
Found another example of this paradigm from scipy.spatial here: import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial import ConvexHull, convex_hull_plot_2d
points = np.random.random((30, 2))
hull = ConvexHull(points)
_ = convex_hull_plot_2d(hull)
plt.show() Here, they use a separate function |
Beta Was this translation helpful? Give feedback.
-
I am definitely in favor of separating plots and computation. Just curious about the advantage to @billtubbs suggestion of creating new types of objects, perhaps built on or inspired by pandas, that include a plot method. I think that would require creation of a series of new classes to hold root locus info, frequency response info, and time response info, to name the new classes I can think of that would be required. Is there a reason it wouldn't be enough to use the simpler alternative of finishing separating out dual-purpose functions like import control as ct
fig, axes = plt.subplots(2, 1)
ax = axes[0]
ct.root_locus_plot(ax=ax)
ax.set_title("System 1")
ax = axes[1]
ct.step_plot(ax=ax)
ax.set_title("System 2")```
* outside of the matlab layer, frequency response plots largely exist: ``nyquist_plot``, ``bode_plot``, ``nichols_plot``, but time response plots don't seem to, e.g. ``step_plot``, ``impulse_plot`` |
Beta Was this translation helpful? Give feedback.
-
@murrayrm , in response to your other point:
I made a quick demo of how this can be done in Pandas: |
Beta Was this translation helpful? Give feedback.
-
FYI, there is a similar concept that has been implemented in JuliaControl PR #529, where they return a result structure for time responses. |
Beta Was this translation helpful? Give feedback.
-
Interesting proposal. During the pandemic, I've developed a simple plotting lib on the top of python control for my students. The lib uses the Plotly backend (which is also supported now by Panda) since my students mainly use the web-based interface Jupyter for running python scripts |
Beta Was this translation helpful? Give feedback.
-
Here is a summary of the relevant analysis and plotting functions currently in Julia ControlSystems (v0.8.0).
Looks like the pattern is to make separate functions for calculations and plotting where applicable. Is there any reason why we didn't name the Python-Control |
Beta Was this translation helpful? Give feedback.
-
Here is a table showing the correspondence between current Julia ControlSystems and Python-Control plot functions and the changes I am proposing to
Can some of you please go through these and provide comments and feedback?
* - these changes are part of a different pull request by Richard. |
Beta Was this translation helpful? Give feedback.
-
Hi @billtubbs,
|
Beta Was this translation helpful? Give feedback.
-
A few comments:
|
Beta Was this translation helpful? Give feedback.
-
I see now that MATLAB has a frequency response data model object which can be legitimately used to store FR data simply for analysis: >> load AnalyzerData
>> sys = frd(resp,freq);
>> sys
sys =
Frequency(rad/s) Response
---------------- --------
0.1000 2.384e-01 - 1.951e-03i
0.1027 2.540e-01 - 3.511e-03i
0.1056 2.430e-01 + 1.807e-03i
0.1085 2.573e-01 - 4.672e-03i
0.1114 2.525e-01 - 7.747e-03i
...
|
Beta Was this translation helpful? Give feedback.
-
I just noticed this comment in python-control/control/freqplot.py Lines 311 to 312 in a111b03 This hadn't occurred to me actually—that you could take an existing subplot axis and divide it into two to make the mag and phase plots. As discussed, my plan was to return a complete new figure and axes: fig, axes = bode_plot(sys) Are there scenarios where we would want to embed a complete (mag + phase) Bode plot inside an existing figure? I think it might be simpler to provide the ability to make individual |
Beta Was this translation helpful? Give feedback.
-
Can anyone think of a good name for this function to provide the calculations we are proposing to remove from counts, contours = ________(syslist, omega=None, omega_limits=None, omega_num=None,
warn_nyquist=True, *args, **kwargs) Docstring:
I'm not entirely sure we will need to keep this function when the new plotting paradigm is complete. Then we only need to return Other thoughts: Or we could return a dictionary called (I checked my French control course notes and there it is "le nombre de tours" which is much more concise!) |
Beta Was this translation helpful? Give feedback.
-
Progress update on my work on this so far. I'm about 75% through step 1 right now. @murrayrm would you prefer me to submit a pull request now or at the end (it passes all the tests including new ones I added). Or I can wait until State 1 is complete: Stage 1 - separate plotting and frequency analysis calculations into separate functions
Stage 2 - Introduce new plotting paradigm for frequency response
|
Beta Was this translation helpful? Give feedback.
-
If you want comments along the way, post as a draft PR and we can take a look at the code and post thoughts. Otherwise, fine to wait until you have something working. Don't forget unit tests (coverage should not go down) and doc/ updates (adding functions, perhaps a new section describing the basic framework). |
Beta Was this translation helpful? Give feedback.
-
Just to confirm. I'm finding code like this in some of the current plotting functions, E.g. from
As I understand it, what this is doing is getting the current figure from pyplot and looking for an axes with the right label and plotting the output to that. Under the changes here, there is the option to pass the axes you want to plot into as an argument and so none of this axes-labelling and searching is needed. Or am I missing something? (I know sisotool and gangof4 plots also use this but I think these functions will be able to use the new approach using the axes argument). |
Beta Was this translation helpful? Give feedback.
-
matplotlib's recommended function signature returns a list of |
Beta Was this translation helpful? Give feedback.
-
@billtubbs I have put this feature on the list for possible release in 0.10.0 (see #917). Are you still working on this/interested in working on this/have the time to work on this? I have some ideas of how to do all of this for time series data (using the |
Beta Was this translation helpful? Give feedback.
-
I've taken a first crack at implementing the new plotting paradigm (#645) for the time response functions. The following code
You can still do old style plotting using this code
(note that Or, if you prefer, you can call the plot function explicitly:
There are lots of options for changing around the way things plot, allowing multiple calls (which plot on the same axes), and more. Some preliminary documentation is here. I'll post this as a PR as soon as #916 gets merged into the main branch (since this set of changes builds on that one). |
Beta Was this translation helpful? Give feedback.
-
See PR #924 for frequency response implementation. Moving on to pole-zero maps (pzmap, rlocus). |
Beta Was this translation helpful? Give feedback.
-
@billtubbs posted in billtubbs/python-control-examples and mentioned in #65 (comment):
Plotting Paradigm
This is a proposal to introduce a different paradigm for the way specialised control analyses and plots are created in Python-Control.
It is based on the way plotting is done in Pandas.
For example:
Functions this proposal could affect
root_locus
pzmap
bode_plot
nyquist_plot
gangof4_plot
nichols_plot
sisotool
?Rationale
The current paradigm for these plot functions is based on the way they are done in MATLAB using the functions
pzmap
,bode
,nyquist
, etc. These functions can produce a plot and/or the data itself, depending on how you use them. This style is typical of a functional programming language that does not have support for object-oriented programming.Problem:
Solution:
The benefits of this approach are:
To illustrate how this might work, I have outlined some examples below.
Example 1 – Root locus plot
Current method:
Proposed method:
or:
Calculate the root locus without making the plot
Current method:
Proposed method:
Calculate and plot the root locus
Current method:
Proposed method:
Customizing the root locus plot
Current method:
Proposed method:
Adding root locus to a custom plot
Current method:
Proposed method:
Other comments
Introducing this would not require the replacement of the MATLAB-like functions
rlocus
,nyquist
,pzmap
, etc. although keeping the currentroot_locus
,bode_plot
, andnyquist_plot
functions seems a bit redundant.Functions such as
freqresp
would be unaffected and would probably be called byFreqResp
to do the calculations.The solution is not going to be as simple as the rlocus example above in the case of all plot functions. Some generate their own axes objects (e.g. radial plots) and some generate more than one axis (i.e. a complete figure), so each function will have to be considered case-by-case.
Beta Was this translation helpful? Give feedback.
All reactions