Skip to content
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

Name collision(s) in pyplot.interactive_plot #295

Open
origen-jak opened this issue Sep 20, 2024 · 0 comments
Open

Name collision(s) in pyplot.interactive_plot #295

origen-jak opened this issue Sep 20, 2024 · 0 comments

Comments

@origen-jak
Copy link

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_plot with a _.: e.g. _xlim
  • Add a validation step to check for name collisions and throw a helpful exception if found. e.g. '_xlim is a reserved name, please change your argument name in function f' 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
@origen-jak origen-jak changed the title Name collision in pyplot.interactive_plot Name collision(s) in pyplot.interactive_plot Sep 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant