3
$\begingroup$

I'm making an animation with Manipulate for a representation. The code looks like this

plot1 = Plot[f[x, y] , {x, -1, 1}, {y, -1, 1}];
Manipulate[{plot0[s], Show[plot1, plot2[s]]}, {s, -1, 1}]

The thing is that plot1 is a large 3D plot requiring complex calculation, but it is independent from s. plot2, which being dependent on s, can be calculated easily (it's just a spinning plane). I've tried

Manipulate[{plot0[s], Show[plot2[s]]}, {s, -1, 1}]

It auto-runs smoothly. But the former code did not perform so well and there were constant interruptions in the animation. So how can I tell Mathematica not to re-evaluate plot1 every time s changes? Since I need plot1 and plot2 in the same Graphics, and synchronized with & juxtaposed next to plot0, I can't really take plot1 out of the Manipulate function. Thanks!

$\endgroup$
4
  • 4
    $\begingroup$ since plot1 is constant already (it is evaluated before even Manipulate does anything), then M does not evaluate it again. What you are seeing in the rendering of it on the screen, which is slow for large objects, not the evaluation. You can try to Rasterize plot1 and see if this improves the rendering performance. $\endgroup$ – Nasser Oct 26 '14 at 7:11
  • $\begingroup$ @Nasser But I kind of need plot1 in 3D. Maybe I have to export the animation. $\endgroup$ – arax Oct 26 '14 at 7:17
  • 1
    $\begingroup$ If you can show the plot1, may be someone can suggest some things. For example, adding Opacity can slow down things quite a bit (since this requires more layers), I remember there was another graphic primitive that was expensive to use but forget it now. You can btw test this yourself. Make a manipulate that only displays plot1, like this Manipulate[x;plot1,{{x,0,"x="},0,1,.1}] and let it run (play the slider). You can now get an idea how long it takes to render plot1 on its own each time. You'll see that the less 3D points/primitive, the faster it will run. $\endgroup$ – Nasser Oct 26 '14 at 8:28
  • $\begingroup$ Would //InputForm help? Save plot1 as its input form? BTW, do you mean Plot3D instead of Plot above? $\endgroup$ – user1722 Oct 26 '14 at 17:37
3
$\begingroup$

My intuition is that the problem is with the front end and not the kernel. The front end will need to render the combined 3D graphics, even if only one changes (unless GPUs have gotten so sophisticated they can manage and compose multiple 3D images -- but on my computer the CPU is heavily engaged).

Speedier rendering

The trick to building a speedier Manipulate is to have two plots, plot1 and a simplified version, which I will call plot1CA. (CA is for ControlActive, about which command you should read, if you do not know it already.)

plot1 = Plot3D[Sin[x y], {x, 0, 6}, {y, 0, 6}, PlotPoints -> 100];
plot1CA = Plot3D[Sin[x y], {x, 0, 6}, {y, 0, 6},
  PlotPoints -> 35, MaxRecursion -> 0, Mesh -> None];

We can estimate the time to render plot1 and plot1CA as follows:

(* two cells -- execute both simultaneously *)
SessionTime[]
plot1     (* <-- important: no semicolon here *)

(*new cell*)
SessionTime[] - %%
(* 0.578488 <-- very slow *)

Similarly...

SessionTime[]
plot1CA

(*new cell*)
SessionTime[] - %%
(* 0.092861 <-- slow but reasonably responsive; reduce PlotPoints further, if desired *)

If your plot is say from ListPlot3D[data], consider downsampling with something like plot1CA = ListPlot3D[data[[;; ;; 10, ;; ;; 10]] (and adjusting DataRange accordingly).

The Manipulate

We can use ControlActive to switch between the full plot and the simplified one.

Manipulate[
 Show[
  ControlActive[plot1CA, plot1],
  Plot3D[(Cos[t] x + Sin[t] y)/6, {x, 0, 6}, {y, 0, 6}, 
   PlotStyle -> Red]
  ],
 {t, 0., 2. Pi}]

Since plot1 and plot1CA have been pre-computed, there is no need to use Dynamic; they are just static data. In fact, we need the whole to be updated, so the image to be rendered can switch between the small amount of data plot1CA when the control is being moved and the larger plot1 when the control is released.

$\endgroup$
2
  • $\begingroup$ @kuba I don't understand what it does that is unnecessary. I think the 3D graphics makes it significantly different that 2D. I think the FE has to calculate the relationship between elements of the static plot1 and the dynamic plot2 every time plot2 is updated, and the delay occurs there, not in the kernel. The kernel can reevaluate plot1 in microseconds, so wrapping it in Dynamic does not save much time. It's different with 2D graphics. (The OP rather confusingly uses Plot and says it's a 3D graphic.) Am I missing something? $\endgroup$ – Michael E2 Nov 6 '14 at 15:20
  • $\begingroup$ You are right, 3D is different story. $\endgroup$ – Kuba Nov 6 '14 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.