Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ENH]: callable arguments to the high level plot functions #20926

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

Closed
akhmerov opened this issue Aug 27, 2021 · 4 comments
Closed

[ENH]: callable arguments to the high level plot functions #20926

akhmerov opened this issue Aug 27, 2021 · 4 comments

Comments

@akhmerov
Copy link
Contributor

Problem

I often find myself using an equivalent of this code:

x = np.linspace(x_min, x_max)
pyplot.plot(x, f(x))

This is unnecessarily verbose, and if written in one line has redundancy:

pyplot.plot(np.linspace(x_min, x_max), f(np.linspace(x_min, x_max)))

Proposed solution

It would be convenient if .plot and similar high level plotting routines identified callable arguments and if possible evaluated those with array arguments. I imagine the amount of meaningful combinations would be limited.

Additional context and prior art

Providing functions as input to plotting routines and letting those take care of the evaluation is a common pattern.

  • Julia has such interface
  • Mathematica goes a step further and determines how to sample the function. This is out of scope for matplotlib.
  • Similarly matlab has fplot
@mwaskom
Copy link

mwaskom commented Aug 28, 2021

Specifically in the case of defining a grid for x and evaluating a function for y* (arguably the only case where automatically evaluating a function would make sense, too), you can use the walrus operator:

plt.plot(x:=np.linspace(xmin, xmax), f(x))

*Should clarify: you could user keyword arguments to rearrange things so that whatever variable you're defining the grid on comes first:

plt.scatter(y=(y:=np.linspace(xmin, xmax)), x=f(y))

But plt.plot does not take keyword arguments for x/y.

@akhmerov
Copy link
Contributor Author

Great idea! This should indeed cover most of the relevant use cases.

@tacaswell
Copy link
Member

We have had at least 2 attempts to add fplot (#1143 and #737) but if I recall correctly they got bogged down in the numerics / theory of how to smartly sample around shape peaks.

If this is something you do all the time, I suggest putting something like

def my_cleverly_named_plotting_of_functions_function(x, f, *, ax=None, **kwargs):
    if ax is None:
        import matplotlib.pyplot as plt
        ax = plt.gca()
   return ax.plot(x, f(x), **kwargs)

in a local library.

For plotting to feel "fluid" it the API needs to be closely tuned to your needs and data, which means the API needs to be opinionated and bake a lot of assumptions in. While there are some cases (like seaborn) where this can be done across a pretty big domain, I think all users should embrace writing mini-libraries exactly tuned to their needs (exactly like we all do with analysis)!


It might also be worth looking at sympy which has a plotting layer that understands sympy objects and "does the right thing" in many cases.


Enabling this sort of thing more generally is one of the goals of @story645 's thesis work. By pulling all of the data management into a dedicated class (rather than stored ad-hoc on the Arstist as now), we will be able to at draw-time query that object with the current view limits (in data space) and axes size (in screen space) to get the relevant data. This will enable things like smart (re-)sampling of the underlying data to be injected into all Matplotlib artists (rather than having to live in the Artist implementation).

@Zero21102
Copy link

Zero21102 commented Aug 28, 2021 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants