- Notifications
You must be signed in to change notification settings - Fork441
Use matplotlibs streamplot function for phase_plane_plot#1112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
coveralls commentedFeb 1, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
This sounds like a great addition. Can you post a few screenshots that show what the new plots look like (since they will be a bit different than the A few thoughts:
|
lkies commentedFeb 2, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Regarding the documentation, just to be clear because it will look inconsistent for now: I only change the docs for what i added so it merges properly with the other changes in#1094 ? Another thing I was not sure about is putting the new parameter to the end of I am not quite sure I understand you correctly but the way you described the exclusion with streamlines does not seem possible since I would also take the opportunity to increase the grid resolution if Another problem I realized is that the norm kind of assumes that the plot will use an equal aspect ratio. So if the derivatives are differently scaled (and the plot has a strongly "non equal" aspect ratio) the larger state will dominate, although handling this might be too much for a convenience function like this. Here are two examples: importcontrolasctimportnumpyasnpimportmatplotlib.pyplotaspltplt.rcParams['figure.figsize']= [6,6]defdydt(t,y):returnnp.array([y[1],-np.sin(y[0])])ct.phase_plane_plot(dydt,plot_streamlines=False,plot_streamplot=dict(vary_linewidth=True),pointdata=[-4,4,-4,4],gridspec=(20,20))plt.gca().set_aspect('equal') The linewidths vary from 0.25 to 2 times the current default linewidth, arguably a matter of opinion but I don't think this should be exposed as arguments. ct.phase_plane_plot(dydt,plot_streamlines=False,plot_streamplot=dict(vary_color=True),pointdata=[-4,4,-4,4])plt.gca().set_aspect('equal') Here you can see the unfortunate z-ordering with the seperatrices that I talked about. While this looks surprisingly good for only 9 by 6 points, I still think the default resolution should be higher. But as you can see, it looks pretty good without having to think much about how to distribute the initial conditions. |
Sounds good.
We'll probably wait until v0.11 to starting using
This lines up with what I was thinking, though it might also make sense to have
Seems fine. Computation is not a major issue here (and if someone has some complicated vector field that takes a long time to compute, they can always change the grid resolution.
Probably OK for now. If needed, we can add some functionality to change the aspect ratio in |
@lkies The big documentation PR has been merged, so you'll need to rebase this on top of the latest main. |
…t and fixed minor documentation issues
I implemented the thing with the
I also get 6 other failed tests, but they also fail on main for me so it should be unrelated.
So depending on if you actually want to have the default changed, which is technically a breaking change, I would consider this done, so I unmarked it as draft. |
In terms of updating the documentation: no matter what we need to update the user guide to saysomething about If you want to leave the default as In terms of the failing tests: what you are showing above is different that what the CI tests are showing. They show the only problem is that you haven't documented I'll do a more careful review of the code in the coming days. |
Ok, I will do that. And thank you for the tip regarding the failing CI test, at first glance I was unsure, whether that file was autogenerated by some process. Do you have a suggestion regarding the test that will fail when changing the default? |
For the unit tests: all we really need is something that executes all of the lines of your code (for coverage) and that will generate an error if the lines don't plot. So perhaps choose some simple set of settings that are easy to check? (And of course it should not work if somehow |
One more thought: if we make |
Ensuring that the separatrices and stationary points are always on top is not too bad, I just tried it and will push it later or tomorrow. I just get the maximum zorder of streamlines, vectorfield or streamplot and then add something to it for seperatrices and equilpoints unless their zorder is already specified. And then the same for equilpoins over separatrices. Although it only requires exposing the zorder for separatrices and equilpoints I would expose it for all 5 functions for consistency. I am not sure if you just wanted to remind me to write tests, but the thing I said about the tests, was that if I set streamplot as the default it would fail the mentioned test ( |
For unit tests, I would keep all current tests, just restructure so that they test with the relevant options. Then add a new test for |
I changed the default plot type to streamplot, implemented the automatic zordering and wrote some tests. I also noticed that |
…nes to be the default
I added the legacy warning / fallback and updated the guide with Is there anything still missing? |
@lkies I created a PR into your repository with a few modifications so that the code and documentation style is consistent with usage throughout the rest of the package. I also updated some of the example scripts to use the new functionality in the appropriate places. If the PR in your repository looks OK, go head and merge it. Once it shows up here, I'll merge this PR into the main branch. Great work overall, and I'm looking forward to having this be the default functionality! |
Update streamplot codestyle, documentation, and figures
@murrayrm No problem, happy to have contributed! |
2a919cc
intopython-control:mainUh oh!
There was an error while loading.Please reload this page.
WORK IN PROGRESS
As the title says, phase_plane_plot currently creates streamlines by integrating a set of initial conditions forwards or backwards in time, while this allows for quite some flexibility it takes more work to get good looking results. Matplotlibsstreamplot is basically made for things like this an produces good looking streamline plots from vector field data, it also makes it very easy to visualize the flows magnitude using varying line thickness or color.
I added a subfunction
phaseplot.streamplot
and the corresponding argumentplot_streamplot
tophase_plane_plot
.There are two options vary_linewidth and vary_color which will vary the linewidth or color depending on the magnitude, they both default to false. You can also pass a colormap or matplotlib norm to make the magnitude to the colors and thicknesses
Some things of note that I am not quite happy with yet:
phase_plane_plot
returns the artist from the individual subfunctions into an array of size 3, adding a fourth element to return the streamplot is technically a breaking change because the array could be used in a destructuring bind. Because of this I didn't add any means of returning the artist yet.Whats your opinion on these problems and what i need to do to get this merged?