2
$\begingroup$

Result on the left is not what I intended to do: it has two sets of Locator points. Trying to determine why two sets of Locator points are appearing. I only intended to have one set.

Result on the right is what I am trying to do: it has one set of Locator points.

Suspect that I am making some fundamental mistake or misunderstanding something. Could someone point out why the results are different? Also, what is an appropriate way to implement this?

Undesired result: Locator points appear twice Desired result: Locator points appear only once

Below is the code for the result on the left. Switch the comments to produce the result on the right. Note these results are for Version 11.0.1.0 Similar, though not always identical, results are obtained for version 10.

Manipulate[
 ptsExtended = Prepend[Append[Sort[ptsAll], {1.5, 1}], {-2, 0}] ;
 fpts   = Interpolation[ptsExtended, InterpolationOrder -> 1];
 dfpts = Derivative[1][fpts];
 plotf   = Plot[fpts[x], {x, 0, 1}, PlotRange -> {{-0.1, 1.1}, {-0.1, 1.1} }, 
   PlotLabel -> Style["f(x)", Bold, 12]];
 plotdf =  Plot[dfpts[x], {x, 0, 1}, PlotRange -> {{-0.1, 1.1}, {-2, 4}}, 
   PlotLabel -> Style["df(x)", Bold, 12]];
 plotSin = Plot[Sin[x], {x, 0, 6}];
 Grid[{{LocatorPane[ptsAll, plotf]}, {plotdf}}](*locator points appear on both plots*)
 (*Grid[{{plotSin},{LocatorPane[ptsAll, plotf]}}]*)(*this works as expected*)
 ,
 (*list of controls*)
 {{ptsAll, initPtsAll}, ControlType -> Locator, LocatorAutoCreate -> True}
 (*other details*)
 , TrackedSymbols :> {ptsAll}
 , Initialization :> (
   initPtsAll = {{0, 0}, {0.25, 0.25}, {0.5, 0.6}, {0.75, 0.85}, {1,1} };
  )
 , SynchronousUpdating -> False
 ]

Finally, this is a simple example of a larger code that I am writing. In the larger code, the Locator points also appear in unexpected (to me) plots.

$\endgroup$
4
  • $\begingroup$ If you comment out the LocatorPane you have there you'll find the locator on the bottom persists. Clearly the system thinks your control spec applies to that bottom graph. Change ControlType to None and leave the LocatorPane uncommented and you should be fine. $\endgroup$
    – b3m2a1
    Mar 15, 2017 at 3:47
  • $\begingroup$ Actually you'll need to provide a Dynamic@ptsAll and initPtsAll too. It might be better just to rewrite this with DynamicModule. $\endgroup$
    – b3m2a1
    Mar 15, 2017 at 3:55
  • $\begingroup$ Removing the LocatorPane, and the LocatorPoints appear only on the plot of df(x). This occurs both when df(x) is on the top and on the bottom of the grid. $\endgroup$
    – user6546
    Mar 15, 2017 at 3:56
  • $\begingroup$ Yep. That's why I said change ControlType->Locator to ControlType->None. And change the locator expression to LocatorPane[Dynamic@ptsAll,plotf,initPtsAll. $\endgroup$
    – b3m2a1
    Mar 15, 2017 at 3:57

2 Answers 2

2
$\begingroup$

So even though I provided a way in the comments to do this with Manipulate, I think this is a case where it's better just to go to DynamicModule. Here's an example of how you could do this:

DynamicModule[{
  ptsExtended, fpts, dfpts,
  plotf, plotdf, plotSin,
  ptsAll, 
  initPtsAll = {{0, 0}, {0.25, 0.25}, {0.5, 0.6}, {0.75, 0.85}, {1, 
     1}},
  genPlots},
 genPlots[] :=
  CompoundExpression[
   ptsExtended =
    Prepend[Append[Sort[ptsAll], {1.5, 1}], {-2, 0}],
   fpts =
    Interpolation[ptsExtended, InterpolationOrder -> 1],
   dfpts =
    Derivative[1][fpts],
   plotf =
    Plot[fpts[x], {x, 0, 1}, PlotRange -> {{-0.1, 1.1}, {-0.1, 1.1}}, 
     PlotLabel -> Style["f(x)", Bold, 12]],
   plotdf =
    Plot[dfpts[x], {x, 0, 1}, PlotRange -> {{-0.1, 1.1}, {-2, 4}}, 
     PlotLabel -> Style["df(x)", Bold, 12]]
   ];
 ptsAll = initPtsAll;
 genPlots[];
 Panel[
  Panel[
   Grid[{
     {(*Dynamic[ptsExtended,UpdateInterval\[Rule].05,
      TrackedSymbols\[RuleDelayed]{}]*)},
     {LocatorPane[Dynamic[ptsAll,
        ptsAll = #; genPlots[]; &],
       Dynamic@plotf]},
     {Dynamic@plotdf}
     }],
   Background -> White
   ],
  FrameMargins -> 15,
  Appearance ->
   FrontEndResource["FEExpressions", 
    "MoreLeftSetterPressedNinePatchAppearance"]
  ],
 Initialization :> (
   initPtsAll = {{0, 0}, {0.25, 0.25}, {0.5, 0.6}, {0.75, 0.85}, {1, 
      1}}
   ),
 SynchronousUpdating -> False
 ]

I think this will exhibit the behavior you desired.

$\endgroup$
3
  • $\begingroup$ Yes, that is the behavior I desired. $\endgroup$
    – user6546
    Mar 15, 2017 at 15:44
  • $\begingroup$ Yes, that is the behavior I desired. Thanks! Can you provide a summary of what this statement is doing: LocatorPane[Dynamic[ptsAll, ptsAll = #; genPlots[]; &], Dynamic@plotf, initPtsAll] What I am trying to understand is a) Dynamic[ptsAll, ptsAll = #; genPlots[]; &] and b) initPtsAll as a third parameter to LocatorPane. When I read the documentation the third parameter is a range for the locator points. $\endgroup$
    – user6546
    Mar 15, 2017 at 15:50
  • $\begingroup$ @user6546 Happily. Dynamic[ptsAll, ptsAll = #; genPlots[]; &] means return ptsAll (for the sake of the LocatorPane but every time a locator is moved call the function ptsAll = #; genPlots[]; & so that the plots regenerate. The Dynamic@plotf is necessary because we want the plot to dynamically update. And the initPtsAll should actually be a the bounding box of your plot, sorry about that. See the docs for what that'll do: LocatorPane. It's an unnecessary tweak. Removed it. $\endgroup$
    – b3m2a1
    Mar 15, 2017 at 15:54
2
$\begingroup$

This is an implementation of the comments from @b3m2a1, regarding how to achieve this result with Manipulate:

Manipulate[
 ptsExtended = Prepend[Append[Sort[ptsAll], {1.5, 1}], {-2, 0}];
 fpts = Interpolation[ptsExtended, InterpolationOrder -> 1];
 dfpts = Derivative[1][fpts];
 plotf = Plot[fpts[x], {x, 0, 1}, 
   PlotRange -> {{-0.1, 1.1}, {-0.1, 1.1}}, 
   PlotLabel -> Style["f(x)", Bold, 12]];
 plotdf = 
  Plot[dfpts[x], {x, 0, 1}, PlotRange -> {{-0.1, 1.1}, {-2, 4}}, 
   PlotLabel -> Style["df(x)", Bold, 12]];
 Grid[{{LocatorPane[Dynamic@ptsAll, plotf, 
     LocatorAutoCreate -> 
      True]}, {plotdf}}](*this works as expected*),(*list of \
controls*){{ptsAll, initPtsAll}, ControlType -> None}
 (*other details*), TrackedSymbols :> {ptsAll}, 
 Initialization :> (initPtsAll = {{0, 0}, {0.25, 0.25}, {0.5, 
       0.6}, {0.75, 0.85}, {1, 1}};), SynchronousUpdating -> False]
$\endgroup$

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.