symplot
Contents
symplot¶
Create interactive plots for sympy
expressions.
The procedure to create interactive plots with for sympy
expressions
with mpl-interactions has been extracted to
this module.
The module is only available here, under the documentation. If this feature turns out to be popular, it can be published as an independent package.
The package also provides other helpful functions, like
substitute_indexed_symbols()
, that are useful when visualizing
sympy
expressions.
- class SliderKwargs(sliders: Mapping[str, Union[FloatSlider, IntSlider]], arg_to_symbol: Mapping[str, str])[source]¶
Bases:
collections.abc.Mapping
Wrapper around a
dict
of sliders that can serve as keyword arguments.Sliders can be defined in
interactive_plot()
through kwargs. This wrapper class can be used for that.- __getitem__(key: Union[str, Symbol]) Union[FloatSlider, IntSlider] [source]¶
Get slider by symbol, symbol name, or argument name.
- set_ranges(*args: Dict[str, Union[Tuple[float, float], Tuple[float, float, Union[float, int]]]], **kwargs: Union[Tuple[float, float], Tuple[float, float, Union[float, int]]]) None [source]¶
Set min, max and (optionally) the nr of steps for each slider.
Tip
n_steps
becomes the step size if its value isfloat
.
- set_values(*args: Dict[str, float], **kwargs: float) None [source]¶
Set initial values for the sliders.
Either use a
dict
as input, or use kwargs with slider names as the keywords (seeSliderKwargs.__getitem__
). This façade method exists in particular forparameter_defaults
.
- property symbol_to_arg: Dict[str, str]¶
Inverted
dict
ofarg_to_symbol
.
- create_slider(symbol: Symbol) Union[FloatSlider, IntSlider] [source]¶
Create an
int
orfloat
slider, depending on Symbol assumptions.The description for the slider is rendered as LaTeX from the
Symbol
name.>>> import sympy as sp >>> from symplot import create_slider >>> create_slider(sp.Symbol("a")) FloatSlider(value=0.0, description='\\(a\\)') >>> create_slider(sp.Symbol("n0", integer=True)) IntSlider(value=0, description='\\(n_{0}\\)')
- partial_doit(expression: Expr, doit_classes: Union[Type[Basic], Tuple[Type[Basic]]]) Expr [source]¶
Perform
doit()
up to a certain level.
- prepare_sliders(expression: Expr, plot_symbol: Union[Symbol, Tuple[Symbol, ...]]) Tuple[Callable, SliderKwargs] [source]¶
Lambdify a
sympy
expression and create sliders for its arguments.>>> import sympy as sp >>> from symplot import prepare_sliders >>> n = sp.Symbol("n", integer=True) >>> x = sp.Symbol("x") >>> expression, sliders = prepare_sliders(x ** n, plot_symbol=x) >>> expression <function _lambdifygenerated at ...> >>> sliders SliderKwargs(...)
- rename_symbols(expression: Expr, renames: Union[Callable[[str], str], Dict[str, str]]) Expr [source]¶
Rename symbols in an expression.
>>> a, b, x = sp.symbols(R"a \beta x") >>> expr = a + b * x >>> rename_symbols(expr, renames={"a": "A", R"\beta": "B"}) A + B*x >>> rename_symbols(expr, renames=lambda s: s.replace("\\", "")) a + beta*x >>> rename_symbols(expr, renames={"non-existent": "c"}) Traceback (most recent call last): ... KeyError: "No symbol with name 'non-existent' in expression"
- substitute_indexed_symbols(expression: Expr) Expr [source]¶
Substitute
IndexedBase
with symbols.See [TR-008] Indexed free symbols for more info.
Examples¶
The following examples show how to work with prepare_sliders()
and the resulting SliderKwargs
. For more explanation about what happens behind the scenes, see Inspect model interactively.
Exponential wave¶
Construct a mathematical expression with sympy
:
import sympy as sp
n = sp.Symbol("n", integer=True)
x, a = sp.symbols("x, a")
expression = sp.sin(n * x) * sp.exp(-a * x)
expression
Create sliders with prepare_sliders()
, set their ranges and (optionally) provide some initial values:
from symplot import prepare_sliders
np_expression, sliders = prepare_sliders(expression, plot_symbol=x)
sliders.set_ranges(
n=(0, 10),
a=(-1, 1, 200),
)
sliders.set_values(n=6, a=0.3)
Now use mpl-interactions to plot the lambdified expression. Note how the SliderKwargs
are unpacked as keyword arguments:
%matplotlib widget
import matplotlib.pyplot as plt
import mpl_interactions.ipyplot as iplt
import numpy as np
plot_domain = np.linspace(0, 10, 1_000)
fig, ax = plt.subplots(figsize=(7, 4))
controls = iplt.plot(
plot_domain,
lambda x, **kwargs: np_expression(x, **kwargs),
**sliders,
ylim="auto",
)
ax.set_xlabel("$x$")
ax.set_ylabel(f"${sp.latex(expression)}$");
Range slider¶
See Using RangeSliders.
np_expression, sliders = prepare_sliders(expression, plot_symbol=x)
sliders.set_values(n=6, a=0.3)
sliders.set_ranges(
n=(0, 10),
a=(-1, 1, 200),
)
def x_domain(x_range, **kwargs):
min_, max_ = x_range
return np.linspace(min_, max_, 1_000)
def f(x, **kwargs):
del kwargs["x_range"]
return np_expression(x, **kwargs)
fig, ax = plt.subplots()
controls = iplt.plot(
x_domain,
f,
x_range=("r", 0, 10),
**sliders,
xlim="auto",
ylim="auto",
)