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.
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$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 thisManipulate[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$