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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make plot API to work directly with axis #19098
Comments
I think the best thing to do would be to make functions that do the boilerplate for lambdify etc in the examples above and produce arguments that are in the suitable form for passing to matplotlib. Then we can just document to users how to pass the results on to matplotlib (or other libraries) and we don't need any specific code for each type of plot except where we have a convenience function like |
These are nice @sylee957. As a start, all of these could be added to the documentation as is. I agree that operating on mpl's Axes objects a good approach (and is standard in most of libraries). As for the future of sympy.plot(), someone needs to lay out a plan to morph it into something better. I like the idea of supporting different backends and think that should remain, but maybe in a different form. It'd be nice to be able to do |
But, maybe, as @oscarbenjamin mentions, SymPy should only output numerical data for given expressions that is in a form for a particular plotting library to consume. Then we'd not have any plotting code present, only data generation code. |
I think this could be a good idea to have it. We can make it simpler by just passing the |
I also agree that having the old plot module can be good because it is more easier to use with some restriction of advanced features. But the features can operate on top of the low-level axex manipulation APIs But the problem of the backend approach is that it is difficult to share options between plots. For example, even if we only have Of course, if the original author of the plotting module had intended to develop more advanced features like drag-able plot or animation, there can be a good point of keeping sympy expression in a plot object. |
The backend approach is a terrible idea as it means that sympy's plotting module has to grow all the API for all of the things that the backends can do. Users and contributors end up wasting their time trying to do things that are already implemented in matplotlib. @sylee957 I think your suggestion here is good and should be used in the current plotting API. Also I think that the documentation and tutorial for plotting should make it very clear that sympy's plotting is just using matplotlib and should show users how to combine sympy with the matplotlib API before mentioning the convenience routines like What I don't think we should do is extend the sympy plotting API apart from providing convenient utilities that users can use to prepare the data for input to other plotting libraries. |
I feel like this kind of statement is certainly what a developer of SymPy might think, not so sure about users of SymPy though. |
I don't think we'd need to give access to many options. The shared backend approach could work in a very constrained way, but provide the user with an underlying object or data structure that can be taken into a specific plotting library when they need something outside of our constraints. For example, if the matplotlib axes object(s) were accessible from our Plot() object in a very simple way, it would open up a lot. You can could create the base MPL plot with a simple command and then operate on the axes with MPL. Seems like the best of both worlds. |
I think this is a good idea. It does call into question the purpose of the
I think that we can make things easier and better for users by making it clear how to use sympy with matplotlib. The OP idea from @sylee957 as well as yours above about providing access to the axes object would both help with that. The most useful thing for users is just being clear that sympy's plotting functionality uses matplotlib which already has many features and plenty of documentation and both of your ideas help to do that. Building a duplicate API on the other hand does not benefit users since the API will always be incomplete and inconsistent with the API that it wraps and its relationship to matplotlib will remain unclear to users. I also think that mission creep is an important problem that sympy needs to worry about. The sympy codebase is already enormous and something like plotting can suck a lot of contributor and user time reimplementing features that already exist in related libraries when for most users all that's really needed is a few utility functions and better documentation. |
I think it is there to take away the boiler plate lambdify and plot setup for typical plots. The other use it currently seems to have is handling some of the numerical issues associated with plotting complex functions (singularities for example). Some functions require non-trival amounts of NumPy and MPL code to get correct. Overall I think there is a place for a symbolic based plot command that "just works". Other symbolic libraries have plot commands. For example, it's nice in Sage that plotting is simple. One use case is using SymPy to teach math. It is a burden to have to explain numpy and matplotlib when you just want a student to see a plot of their math expression. I use SymPy's plot function for this often.
Agreed.
That calls for a separate thread 😄 |
That's what the plot function does. What I mean is what is the purpose of the
Where possible that should be improved in other parts of sympy to make it easier rather than being part of the plotting module.
I agree that it is good to have a simple plot command. I just want it to remain simple and the documentation should make it clear that it is deliberately simple and is just a wrapper for another library so that it is clear to everyone how to access the more advanced features that are already available from the other library. There is definite benefit for sympy to implement domain-specific plotting features that are not implemented somewhere else but we need to be careful not to end up in a situation of reimplementing things that already exist elsewhere. An example of something that is nontrivial and makes sense for sympy but is not implemented directly in matplotlib is domain colouring: |
Although the frontend-backend approach used in And I'm afraid that changing the return types of plot is not trivial and can cause a lot of deprecation issues, and it can confuse users in other way if we cannot provide much reason about how such features were just experimental and it had to be deprecated after some trials. I think that frontend-backend approach is valid in the sense that there are some distinguishable 'major' features from minor options for plots. The concern only happens when too much trivial or implementation-specific options are added for plots, and if we are unable to control how such keywords mangles each other, but I think that the contemporary CAS softwares can be reviewed to investigate whether addition of some plotting options are really necessary or not. |
I think that a lot of plotting API can be redone by making functions that take matplotlib
Axes
and operates in-place toAxes
to append the data points and options to work with existing matplotlib instsance, rather than building the plot from scratch.And we may need stuff more corresponding to the matplotlib object-oriented API than pyplot API, https://matplotlib.org/api/index.html#the-object-oriented-api.
However, this can still be tricky to supersede all the options that matplotlib have. For example, plotting API can often have parametric color specifications. And if that is available in some plotting API, it should have match with sympy functions or geometric primitives.
The text was updated successfully, but these errors were encountered: