3
$\begingroup$

I'm doing this manipulation where there is a mapping between functions as follows.
However, why does it not work when I substitute {myfunc, colors, colors, Range[Length@list], {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2}} with {myfunc, colors, colors, Range[Length@list], list}?
How could I speed up this code?
The problem is that each curve is plotted separately and then combined with Show.
It becomes slow when the number of functions increase and many formating options in each plot are added.
Also the formating options overlaps because of Showso it is not easy to set up desired formating as you have to think about how many overlapping plots instead of just one.

func[t_] := (t^2 - 1)/3;
list = {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2};
myfunc = func /@ list /. c -> t ;
colors = ColorData[97] /@ Range[Length@list];

Manipulate[
 Dynamic@Show[
   MapThread[
    ReplaceAll[
       p_Point :> {p, 
         Text[Style[#4, 14], Offset[{5, 5}, p[[1]]], {-1, -1}]}]@
      Normal@Plot[#, {t, 0.5, 10}, Mesh -> {{#5}}, 
        MeshStyle -> Directive[PointSize@Large, #2], PlotStyle -> #3, 
        GridLines -> Automatic, ImageSize -> Large] &, {myfunc, 
     colors, colors, 
     Range[Length@list], {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2}}]],
 {c, 1, 10, AnimationRate -> 1/3}]

enter image description here

$\endgroup$
6
  • $\begingroup$ what is colors ? $\endgroup$
    – Nasser
    Mar 29 at 1:18
  • $\begingroup$ @Nasser thanks, I just added. $\endgroup$
    – hana
    Mar 29 at 1:27
  • 1
    $\begingroup$ It becomes slow when the number of functions increase Using the example you posted, I see no slow down. It runs fast when I move the slider. Using V 13. It is better to post an example that shows the actual issue in this case. $\endgroup$
    – Nasser
    Mar 29 at 1:30
  • $\begingroup$ @Nasser it was slow so I removed all formating options and it is still slow. It probably due to my slow PC. $\endgroup$
    – hana
    Mar 29 at 1:51
  • 2
    $\begingroup$ Well, it runs very fast for me. You can try this version I just made (will post it as answer then remove the answer when you copy it as easier than here in comment). $\endgroup$
    – Nasser
    Mar 29 at 2:00

3 Answers 3

3
$\begingroup$

Like others, I don't see poor performance in the example. However, one way to improve performance in general is to separate static computations from the dynamic ones. For instance the plots do not change, just the points. So separate out the plots and put the points inside their own Dynamic[]. One other thing, Manipulate localizes control variables, so the OP's c inside Manipulate and the c inside list do not represent the same variable. To fix this, one way is to use a different variable in Manipulate and substitute it in for c. The substitution may be done expr /. c -> c0 or with Block as shown below.

func[t_] := (t^2 - 1)/3;
list = {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2} ~
   Join~ (c*Range[0, 1, 1/10]);  (* add some extra functions *)
myfunc = func /@ list /. c -> t;
colors = ColorData[97] /@ Range[Length@list];

Manipulate[
 Dynamic@
  Show[
   (*Beep[];*)  (* Beep[] gives evidence of non/reevaluation *)
   MapThread[
    Plot[#, {t, 0.5, 10}, PlotStyle -> #2, GridLines -> Automatic, 
      ImageSize -> Large] &, {myfunc, colors}],
   Graphics[
    Dynamic@
     Block[{c = c0},
      MapThread[
       With[{p = Point[{#5, #1 /. t -> #5}]},
         {PointSize@Large, #2, p, 
          Text[Style[#4, 14], 
           Offset[{5, 5}, p[[1]]], {-1, -1}]}] &, {myfunc, colors, 
        colors, Range[Length@list], list}]
      ]
    ]
   ],
 {{c0, 1, HoldForm[c]}, 1, 10, AnimationRate -> 1/3}]
$\endgroup$
5
$\begingroup$

You can copy and try this to see if it is faster.

func[t_] := (t^2 - 1)/3;
list = {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2};
myfunc = func /@ list /. c -> t
colors = ColorData[97] /@ Range[Length@list];

Manipulate[
 Show[MapThread[
   ReplaceAll[
      p_Point :> {p, 
        Text[Style[#4, 14], Offset[{5, 5}, p[[1]]], {-1, -1}]}]@
     Normal@Plot[#, {t, 0.5, 10}, Mesh -> {{#5}}, 
       MeshStyle -> Directive[PointSize@Large, #2], PlotStyle -> #3, 
       GridLines -> Automatic, ImageSize -> Large] &,
   {myfunc, colors, colors, 
    Range[Length@list], {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2}}
   ]
  ],
 {c, 1, 10, AnimationRate -> 1/3},
 TrackedSymbols :> {c}
 ]
$\endgroup$
4
$\begingroup$

For me it works okay. My computer is Win7-x64/8GB/no SSD, Corei5,3rdgen.

Regarding your query:

why does it not work when I substitute {myfunc, colors, colors, Range[Length@list], {c, (1 + 2 c)/3, 3 c, c^2, (1 + c)/2}} with {myfunc, colors, colors, Range[Length@list], list}?

Wrap manipulate with With. See the color change for the list=list. You have to set list locally:

With[{list = list},
 Manipulate[
  Dynamic@
   Show[MapThread[
     ReplaceAll[
        p_Point :> {p, 
          Text[Style[#4, 14], Offset[{5, 5}, p[[1]]], {-1, -1}]}]@
       Normal@Plot[#, {t, 0.5, 10}, Mesh -> {{#5}}, 
         MeshStyle -> Directive[PointSize@Large, #2], PlotStyle -> #3,
          GridLines -> Automatic, ImageSize -> Large] &, {myfunc, 
      colors, colors, Range[Length@list], list}]], {c, 1, 10, 
   AnimationRate -> 1/3}]
 ]
$\endgroup$
2
  • 1
    $\begingroup$ I do not see why Dynamic is needed inside Manipulate. Manipulate itself is Dynamic module ? excessive use of Dynamic and in the wrong place can cause slow down if one is not careful. I try to use explicit Dynamic only when absolutely needed. $\endgroup$
    – Nasser
    Mar 29 at 2:10
  • $\begingroup$ I agree; and thanks for bringing it up. The OP can explore DynamicModule as well. $\endgroup$
    – Syed
    Mar 29 at 2:12

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.