From 0bc7f27ae24547b76bc6238e0e1bc1efd624382c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Davide=20Sandon=C3=A0?= Date: Sun, 14 Apr 2024 11:10:20 +0200 Subject: [PATCH] updated docs --- README.md | 42 ++++++++++++++++----------- TODO.md | 14 +++++---- doc/source/conf.py | 3 +- doc/source/index.rst | 33 ++++++++++++++++++--- doc/source/modules/backends/index.rst | 40 +++++++++++-------------- doc/source/modules/renderers.rst | 4 --- doc/source/overview.rst | 22 +++----------- spb/backends/base_backend.py | 27 +++++++++-------- 8 files changed, 100 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index d6c5194d..06fb3fdc 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,12 @@ [![Conda Version](https://img.shields.io/conda/vn/conda-forge/sympy_plot_backends.svg)](https://anaconda.org/conda-forge/sympy_plot_backends) [![Documentation Status](https://readthedocs.org/projects/sympy-plot-backends/badge/?version=latest)](http://sympy-plot-backends.readthedocs.io/) ![Coverage](https://github.com/Davide-sd/sympy-plot-backends/blob/master/coverage.svg) +[![](https://img.shields.io/static/v1?label=Github%20Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/Davide-sd) This module contains a few plotting backends that can be used with [SymPy](github.com/sympy/sympy) and [Numpy](https://github.com/numpy/numpy). A backend represents the plotting library: it provides the necessary functionalities to quickly and easily plot the most common types of symbolic expressions (line plots, surface plots, parametric plots, vector plots, complex plots, control system plots). -The following plotting libraries are supported: [Matplolib](https://matplotlib.org/), [Plotly](https://plotly.com/), [Bokeh](https://github.com/bokeh/bokeh), [K3D-Jupyter](https://github.com/K3D-tools/K3D-jupyter), [Mayavi](https://github.com/enthought/mayavi). +The following plotting libraries are supported: [Matplolib](https://matplotlib.org/), [Plotly](https://plotly.com/), [Bokeh](https://github.com/bokeh/bokeh), [K3D-Jupyter](https://github.com/K3D-tools/K3D-jupyter).
@@ -30,24 +31,30 @@ On top of the usual plotting functions exposed by SymPy (`plot`, * visualize 2D/3D vector fields with quivers or streamlines. * visualize complex functions with [domain coloring](https://en.wikipedia.org/wiki/Domain_coloring). * visualize entities from the `sympy.geometry` module. -* visualize control systems' response to input signals, visualize Bode, Nyquist and Nichols plots. +* visualize control systems' response to input signals, root locus, as well as Bode, Nyquist and Nichols diagrams. * create parametric-interactive plots using widgets (sliders, buttons, etc.) with *ipywidgets* or *Holoviz's Panel*. -* combine multiple plots into a grid-like layout. Please, read the [following documentation page](https://sympy-plot-backends.readthedocs.io/en/latest/overview.html#differences-with-sympy-plotting) to understand the differences between this module and ``sympy.plotting``. -If you feel like some feature could be implemented, open an issue or create -a PR. +## Development and Support -## Explore the Capabilities +If you feel like a feature could be implemented, open an issue or create a PR. -[Read the documentation](https://sympy-plot-backends.readthedocs.io/) to -explore the capabilities before the installation, which contains plenty of -examples. +If you really want a new feature but you don't have the capabilities or the +time to make it work, I'm willing to help; but first, open an issue or send +me an email so that we can discuss a sponsorship strategy. + +Developing this module and its documentation was no easy job. Implementing +new feature and fixing bugs requires time and energy too. If you found this +module useful, you can show your appreciation by sponsoring this project: + +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/davide_sd) +or +[![](https://img.shields.io/static/v1?label=Github%20Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/Davide-sd) ## Installation @@ -72,7 +79,14 @@ plotly, k3d, vtk, execute the following command: pip install sympy_plot_backends[all] ``` -Or: +If you are using zshell, the above `pip` command is going to fail. +Use the following instead: + +``` +pip install "sympy_plot_backends[all]" +``` + +Or, if you are using `conda`: ``` conda install -c anaconda scipy notebook colorcet @@ -84,15 +98,9 @@ conda install -c bokeh ipywidgets_bokeh conda install -c conda-forge k3d msgpack-python conda install -c plotly plotly conda install -c conda-forge vtk +conda install -c conda-forge control slycot ``` -Finally, if you are using zshell, the above `pip` command is going to fail. -Use the following instead: - -``` -pip install "sympy_plot_backends[all]" -``` - ## Warnings diff --git a/TODO.md b/TODO.md index a5c98a15..334250b1 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ ## TODO -- [ ] enable the user to provide existing figures and plot over them. +In no particular order: - [ ] Implement parallel evaluation when `modules="mpmath"` or `modules="sympy"`. [Motivational example](https://stackoverflow.com/a/77163667/2329968). @@ -11,10 +11,10 @@ - [ ] `plot_implicit`: decouple `And` expressions and plot them with contours following a strategy similar to sage. -- [ ] 3D vector fields discretizing the volume with two polar parameters, or +- [ ] 3D vector fields: discretize the volume with two polar parameters, or two cylindrical parameters. -- [ ] `plot_nyquist` and `plot_nichols` for Plotly/Bokeh. +- [ ] Control system plotting for Plotly. - [ ] implement parametric-widgets support for `xlim, ylim, zlim` and `xlabel, ylabel, zlabel`. @@ -24,8 +24,10 @@ - [ ] Create a way to apply rotation/translation/scaling transformation to 3D entities (obviously, with interactive plotting in mind). -- [ ] custom legend position with keyword argument. +- [ ] Custom legend position with keyword argument. -- [ ] wireframe lines for iso-modulus, iso-phase on `analytic_landscape`. +- [ ] Apply `pi` tick format to axis labels. -- [ ] asymptotes on 3D plots: probably requires to break mesh connectivity. +- [ ] Wireframe lines for iso-modulus, iso-phase on `analytic_landscape`. + +- [ ] Asymptotes on 3D plots: probably requires to break mesh connectivity. diff --git a/doc/source/conf.py b/doc/source/conf.py index 056fa89f..447b0cdf 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -66,7 +66,8 @@ 'sphinx_plotly_directive', 'sphinx_panel_screenshot', 'sphinx_k3d_screenshot', - 'sphinx_math_dollar' + 'sphinx_math_dollar', + 'sphinx_design' ] # nbsphinx_allow_errors = True diff --git a/doc/source/index.rst b/doc/source/index.rst index 844c46cd..97cc4421 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -9,9 +9,9 @@ Welcome to Sympy Plotting Backends's documentation! This Python module contains a few plotting backends that can be used with `SymPy `_ and `Numpy `_. A backend represents the plotting library: -it provides the necessary functionalities to quickly creates the most common -types of plots, such as line plots, surface plots, parametric plots, -vector plots, complex plots, geometric plots. +it provides the necessary functionalities to quickly and easily plot the most +common types of symbolic expressions (line plots, surface plots, +parametric plots, vector plots, complex plots, control system plots). Most of the plotting functions can also automatically generates widgets (sliders, buttons, ...) starting from symbolic expressions. It allows to @@ -30,8 +30,33 @@ without the knowledge of complicated widget libraries. :width: 220 :alt: 3D surface + +Development and Support +======================= + +If you feel like a feature could be implemented, open an issue or create a PR. + +If you really want a new feature but you don't have the capabilities or the +time to make it work, I'm willing to help; but first, open an issue or send +me an email so that we can discuss a sponsorship strategy. + +Developing this module and its documentation was no easy job. Implementing +new feature and fixing bugs requires time and energy too. If you found this +module useful, you can show your appreciation by sponsoring this project: + +.. button-link:: https://www.buymeacoffee.com/davide_sd + :color: primary + + :fas:`mug-hot;fa-xl` Buy me a Coffee + +.. button-link:: https://github.com/sponsors/Davide-sd + :color: primary + + :fab:`github;fa-xl` Github Sponsor :fas:`heart;fa-xl` + + .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Contents: overview.rst diff --git a/doc/source/modules/backends/index.rst b/doc/source/modules/backends/index.rst index 9e8b41e6..cb932d79 100644 --- a/doc/source/modules/backends/index.rst +++ b/doc/source/modules/backends/index.rst @@ -3,33 +3,32 @@ Backends .. toctree:: - :maxdepth: 2 + :maxdepth: 1 plot.rst matplotlib.rst bokeh.rst plotly.rst k3d.rst - mayavi.rst -This module allows the user to chose between 5 different backends. +This module allows the user to chose between 4 different backends. The use case is summarized in the following table. -+------------------------+-----------+-------+--------+------+--------+ -| | Matplolib | Bokeh | Plotly | K3D | Mayavi | -+========================+===========+=======+========+======+========+ -| 2D | Y | Y | Y | N | N | -+------------------------+-----------+-------+--------+------+--------+ -| 3D | Y | N | Y | Y | Y | -+------------------------+-----------+-------+--------+------+--------+ -| Latex Support | Y | N | Y | Y | Y | -+------------------------+-----------+-------+--------+------+--------+ -| Jupyter NB | Y | Y | Y | Y | Y | -+------------------------+-----------+-------+--------+------+--------+ -| Python Interpreter | Y | Y | Y | N | Y | -+------------------------+-----------+-------+--------+------+--------+ -| Interactive Widgets | Y | Y | Y | Y | N | -+------------------------+-----------+-------+--------+------+--------+ ++------------------------+-----------+-------+--------+------+ +| | Matplolib | Bokeh | Plotly | K3D | ++========================+===========+=======+========+======+ +| 2D | Y | Y | Y | N | ++------------------------+-----------+-------+--------+------+ +| 3D | Y | N | Y | Y | ++------------------------+-----------+-------+--------+------+ +| Latex Support | Y | N | Y | Y | ++------------------------+-----------+-------+--------+------+ +| Jupyter NB | Y | Y | Y | Y | ++------------------------+-----------+-------+--------+------+ +| Python Interpreter | Y | Y | Y | N | ++------------------------+-----------+-------+--------+------+ +| Interactive Widgets | Y | Y | Y | Y | ++------------------------+-----------+-------+--------+------+ In particular: @@ -48,7 +47,6 @@ In particular: * Lack of gradient lines. * Doesn't support ``plot_implicit``. * Contour capabilities are limited in comparison to Matplotlib. - * No wireframe support for 3D plots. * Bokeh: interactivity and data exploration are great. It supports auto-update while panning the plot (only works with 2D lines), however: @@ -65,10 +63,6 @@ In particular: scale the visualization. What you see is the object as you would see it in reality. -* Mayavi only support 3D plots. Differently from K3D, a custom aspect ratio - can be used. However, it offers much more customization options after the - plot has been created. - We can choose the appropriate backend for our use case at runtime by setting the keyword argument ``backend=`` in the function call. We can also set the default backends for 2D and 3D plots in a configuration file by using the :doc:`Defaults module <../defaults>` . diff --git a/doc/source/modules/renderers.rst b/doc/source/modules/renderers.rst index e35ad3d0..87b02f89 100644 --- a/doc/source/modules/renderers.rst +++ b/doc/source/modules/renderers.rst @@ -7,7 +7,3 @@ Renderers .. autoclass:: Renderer - -.. module:: spb.backends.matplotlib.renderers.renderer - -.. autoclass:: MatplotlibRenderer diff --git a/doc/source/overview.rst b/doc/source/overview.rst index 7f8fc627..f04ea09b 100644 --- a/doc/source/overview.rst +++ b/doc/source/overview.rst @@ -22,9 +22,7 @@ libraries): `Matplotlib `_, `Plotly `_, `Bokeh `_, -`K3D-Jupyter `_, -`Mayavi `_ (support for this backend -is limited). +`K3D-Jupyter `_. The 3 most important reasons for supporting multiple backends are: @@ -37,10 +35,7 @@ The 3 most important reasons for supporting multiple backends are: translates to better data exploration and visualization (especially when working with Jupyter Notebook). -#. To use the **plotting library we are most comfortable with**. The backend - can be used as a starting point to plot symbolic expressions; then, we could - use the figure object to add numerical (or experimental) results using the - commands associated to the specific plotting library. +#. To use the **plotting library we are most comfortable with**. More information about the backends can be found at: :doc:`Backends ` . @@ -51,9 +46,7 @@ Examples The following code blocks shows a few examples about the capabilities of this module. Please, try them on a Jupyter Notebook to explore the interactive -figures. Alternatively, consider loading the ``html`` output when available: -note that changing the state of widgets won't update the plot as there is no -active Python kernel running on this web page. +figures. Interactive-Parametric 2D plot of the magnitude of a second order transfer @@ -264,21 +257,14 @@ Differences with sympy.plotting * While the backends implemented in this module might resemble the ones from the `sympy.plotting` module, they are not interchangeable. -* `sympy.plotting` also provides a ``Plotgrid`` class to combine multiple plots - into a grid-like layout. This module replaces that class with the - ``plotgrid`` function. Again, they are not interchangeable. - * The ``plot_implicit`` function uses a mesh grid algorithm and contour plots by default (in contrast to the adaptive algorithm used by `sympy.plotting`). 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. -* ``experimental_lambdify``, used by `sympy.plotting`, has been completely - removed. - * `sympy.plotting` is unable to visualize summations containing infinity in - their lower/upper bounds. The new module introduces the ``sum_bound`` keyword + their lower/upper bounds. This module introduces the ``sum_bound`` keyword argument into the ``plot`` function: it substitutes infinity with a large integer number. As such, it is possible to visualize summations. diff --git a/spb/backends/base_backend.py b/spb/backends/base_backend.py index 41790b03..6c5467a1 100644 --- a/spb/backends/base_backend.py +++ b/spb/backends/base_backend.py @@ -17,20 +17,23 @@ class Plot: 1. The user creates the symbolic expressions and calls one of the plotting functions. - 2. The plotting functions generate a list of instances of the `BaseSeries` - class, containing the necessary information to plot the expressions - (eg the expression, ranges, series name, ...). Eventually, these - objects will generate the numerical data to be plotted. - 3. The plotting functions instantiate the `Plot` class, which stores the + 2. The plotting functions generate a list of instances of ``BaseSeries``, + containing the necessary information to generate the appropriate + numerical data and create the proper visualization + (eg the expression, ranges, series name, ...). + 3. The plotting functions instantiate the ``Plot`` class, which stores the list of series and the main attributes of the plot (eg axis labels, - title, etc.). Among the keyword arguments, there must be `backend`, - a subclass of `Plot` which specify the backend to be used. - 4. The backend will render the numerical data to a plot and (eventually) - show it on the screen. The figure is populated with numerical data once - the `show()` method or the `fig` attribute are called. + title, etc.). Among the keyword arguments, there must be ``backend=``, + where a subclass of ``Plot`` can be specified in order to use a + particular plotting library. + 4. Each data series will be associated to a corresponding renderer, which + receives the numerical data and add it to the figure. A renderer is also + responsible to keep objects up-to-date when interactive-widgets plots + are used. The figure is populated with numerical data when the + ``show()`` method or the ``fig`` attribute are called. The backend should check if it supports the data series that it's given. - Please, explore the `MatplotlibBackend` source code to understand how a + Please, explore ``MatplotlibBackend`` source code to understand how a backend should be coded. Also note that setting attributes to plot objects or to data series after @@ -48,7 +51,7 @@ class Plot: * ``save(self, path, **kwargs)``: used to save the current plot to the specified file path. * ``self._fig``: an instance attribute to store the backend-specific plot - object, which can be retrieved with the `Plot.fig` attribute. This + object, which can be retrieved with the ``Plot.fig`` attribute. This object can then be used to further customize the resulting plot, using backend-specific commands. * ``update_interactive(self, params)``: this method receives a dictionary