-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Bug report
My first time using this library and just by chance I managed to run into a weird edge case in the first few minutes:
Bug summary
If you use a variable name in your target function, that is also declared in the pyplot.interactive_plot function, it'll throw a confusing TypeError due to the name collision. For me it was declaring a variable named xlim.
Code for reproduction
Using the Basic example from the doc's, but changing the declared variable name in the user defined function f to trigger a name collision:
%matplotlib ipympl
import matplotlib.pyplot as plt
import numpy as np
import mpl_interactions.ipyplot as iplt
# Name collision defined here: xlim
def f(x, xlim, beta):
return np.sin(x * xlim) * x**beta
x = np.linspace(0, 2 * np.pi, 1000)
xlim = np.linspace(5, 10)
beta = np.linspace(0.25, 1)
fig, ax = plt.subplots()
controls = iplt.plot(x, f, xlim=xlim, beta=beta) # Pow!Actual outcome
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[1], line 15
12 beta = np.linspace(0.25, 1)
14 fig, ax = plt.subplots()
---> 15 controls = iplt.plot(x, f, xlim=xlim, beta=beta)
File ...\mpl_interactions\pyplot.py:227, in interactive_plot(parametric, ax, slider_formats, xlim, ylim, force_ipywidgets, play_buttons, controls, display_controls, *args, **kwargs)
224 controls._register_function(update, fig, params.keys())
226 if x_and_y:
--> 227 x_, y_ = eval_xy(x, y, params)
228 if fmt:
229 lines = ax.plot(x_, y_, fmt, **plot_kwargs)
File ...\mpl_interactions\helpers.py:173, in eval_xy(x_, y_, params, cache)
171 cache[y_] = y
172 else:
--> 173 y = y_(x, **params)
174 else:
175 y = y_
TypeError: f() missing 1 required positional argument: 'xlim'
The exception thrown is confusing as it classifies xlim as a missing positional argument, when the user supplied it as a keyword argument.
Expected outcome
The code should work without throwing an exception, exactly as in the documentation.
Some ideas for a fix:
- prefix all the variables declared in
interactive_plotwith a_.: e.g._xlim - Add a validation step to check for name collisions and throw a helpful exception if found. e.g. '
_xlimis a reserved name, please change your argument name in functionf' or similar.
Thanks for your work, it's a helpful package.
Version Info
- Operating system: Windows 11
- Matplotlib version: 3.8.0
- Matplotlib backend (
print(matplotlib.get_backend())): ipympl.backend_nbagg - Python version: 3.11.5