# Decouple computing data for a plot and creating the plot object?

The plot() function does Two Things:

1. takes your function and samples its values (somewhat intelligently) to create a list of 2D coordinate pairs
2. uses that list of coordinates to create a plot object

Is there a way to decouple these steps, i.e. separately invoke the logic of step 1 to obtain a list of 2D points and then the logic of step 2 to obtain the plot object?

The motivation for this is computing different curves of a composite plot on different cores using @parallel. Very unfortunately the return value of plot(), whatever it is, doesn't pickle/unpickle properly, and thus cannot be returned between threads. So if you generate separate plot objects in your @parallel function, all you will get at the call point will be an iterator yielding error messages. This could be avoided if I could _just_ compute the 2D data lists in threads, and "render" them to a plot in the main thread.

Is that doable?

Please be aware that I am interested in using plot()'s actual logic for sampling the plotted function, rather than writing my own logic that would probably be inferior.

EDIT: toy example

@parallel
def singlePlot(v):
x = var('x')
return plot((x-v)^2, xmin=-3, xmax=3)

plots = [];
for onePlot in singlePlot([0,1,2,3]):
plots.append(onePlot)

plots[0]


Outputs:

(((0,), {}), "INVALID DATA invalid load key, 'x'.")


The same singlePlot() function works as expected if I remove the @parallel decorator and call it with a single integer rather than a list.

edit retag close merge delete

Something close to the final result can be achieved by plotting a list of functions, e. g. :

sage: plot([tan(x*u) for u in range(1, 4)], (x, -pi, pi), detect_poles="show", ymin=-3, ymax=3)
Launched png viewer for Graphics object consisting of 27 graphics primitives


but I see no way to achieve the use of paralel processes for each value of the parameter u. plot should setup an asynchronous call for each value of xaccording to u and a rendez-vous mechanism for collecting the results. Interesting only if the comutation of f strongly outwheights these mechanisms.

A possible way would be to isolate the grid comuting algorithm of \$SAGE_ROOT/src/sage/plot/plot.py (lines 2295 to 2375 approximatively + the dependencies). That's heavy work... of questionable usefulness..

( 2022-11-02 14:20:32 +0100 )edit

Yes, in the real application the computation of f strongly outweighs these mechanisms, unlike in the toy example.

( 2022-11-07 16:05:49 +0100 )edit

How is the ability to compute something 12 times faster "of questionable usefulness"?

( 2022-11-07 22:50:45 +0100 )edit