-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Description
A few months ago NumFocus selected my proposal to implement a new plotting module for SymPy. Now that the development is done, @oscarbenjamin and @asmeurer suggested to open this issue in order to understand if/how this module can be integrated into SymPy.
Proposal - Objectives
The aim of this proposal is to integrate different new open-source technologies. In particular:
- Integration of different plotting libraries: Matplotlib, Bokeh, Plotly, K3D-Jupyter, etc. where the latters are native-interactive. This would allow the user to choose the best library for the specific problem (or based on the user preference).
- Integration of holoviz’s panel and param libraries: together with the aforementioned native-interactive plotting libraries, this enables the creation of a function,
iplot
(interactive-plot), to visually explore symbolic expressions by changing the parameters using widgets (sliders, checkboxes, buttons, etc.) with a single command and virtually no knowledge of panel/param. - Add a function to easily and quickly extract numerical data from the supported types of plot in order to create custom plots. The current procedure is manually-intensive and must be adapted to the specific case.
- Add functions to quickly visualize 2D/3D vector fields, complex numbers and complex functions. Integrate them with the
iplot
function. - Refactoring of the
MatplotlibBackend
: the current implementation (inherited from SymPy) is blocking its integration with theiplot
function. - Writing all the necessary documentation and examples in order to take full advantage of the module.
- Improve singularity handling for plots (SymPy issue Improve singularity handling for plots #18455).
- Improve support for plotting Piecewise functions (the discontinuities must be visible, at least in 2D plots).
Results
The new plotting module is available at this Github repository. All the previous plotting functions are available, as well as new ones:
plot_list
: add custom numerical data to the plot.plot_polar
: create polar plots...plot_geometry
: plot entities fromsympy.geometry
plot_piecewise
: visualizePiecewise
expressions with their discontinuities.plot_vector
: visualize 2D/3D vector fields with quivers or streamlines.plot_complex
,plot_complex_list
,plot_real_imag
,plot_complex_vector
deal with complex functions.iplot
is a general function that allows to create interactive plots with widgets (sliders, checkboxes, ...) starting from symbolic expression.plotgrid
to combine multiple plots into a grid-like layout.
By looking at the documentation you'll be able to explore the new (and old) plotting functions as well as their output.
A few notebook tutorials are available in the repository: they are designed to illustrate the capabilities and the differences between the backends (the plotting libraries). Sadly, they must be executed locally, as Nbviewer is unable to load all javascript-based plots.
Back Compatibility (or lack of)
While the plotting functionalities are overall similar to the current sympy.plotting
, there are some important differences:
- In
sympy.plotting
,Plot
andMatplotlibBackend
are unrelated (in OOP terms). The instances of these two classes create a cross reference. In this new module,Plot
serves as a base class toMatplotlibBackend
(and every other backend). - In
sympy.plotting
, each*Series
class has its own method to return numerical data (for exampe,get_data()
,get_meshes()
,get_raster()
). In the new module all series only exposesget_data()
. sympy.plotting
exposes thePlotGrid
class. This has been removed in favor of theplotgrid
function, which is also able to combine plots created with different backends.- The adaptive algorithm is also different: this module relies on adaptive, which allows more flexibility.
- The
depth
keyword argument has been removed, whileadaptive_goal
andloss_fn
have been introduced to control the new module. - It has also been implemented to 3D lines and surfaces.
- It allows to generate smoother line plots, at the cost of performance.
- The
sympy.plotting
exposed thenb_of_points_*
keyword arguments. These have been replaced withn
orn1, n2
.sympy.plotting
exposed thelabel
,line_color
andsurface_color
keyword argument (both of plotting functions and data series). These have been removed in this module. It means that withsympy.plotting
we could modify the appearance of a plot after aPlot
object was created. This is not supported with the new module: all customization options must be provided when a plotting function is called.- The
plot_implicit
function has different signature. Moreover, by default it uses a mesh grid algorithm and contour plots (in contrast to the adaptive algorithm). It is going to automatically switch to an adaptive algorithm if Boolean expressions are found. This ensures a better visualization for non-Boolean implicit expressions. - Almost completely removed the dependency on
sympy.plotting.experimental_lambdify
in favor oflambdify
. Complete removal will be achieved if lambdify - differences betweenand
and&
#23010 will be solved.
Testing
Several tests have been implemented on this new module. In particular:
- All testing available in
sympy.plotting
has been incorporated (some tests have been modified to account for the differences of this new module). - Added tests to assure that
*Series
classes correctly generates data. - Added tests to assure that plotting functions are able to pre-process their arguments (for example, when plotting piecewise expressions or summations).
- Added tests to assure that backends provide a common user experience.
Discussion
There are many things to discuss:
- Notably, if this new modules is going to be merged into SymPy, how do we deal with the old plotting module? Remember, all plotting functions available on
sympy.plotting
are also available in the new module. - If the module will be merged, SymPy would need to use further dependencies on testing.
- If you have specific questions about why I changed something, I'll provide a detailed answer.
- Install the new module and try it. Read the documentation, follow the tutorials. If you find bugs or if you think the documentation can be improved, please let me know either with an issue or a comment down below.