I would like to make the locator follow a plot, giving the coordinates as it moves. I don't really know where to start with this one, but I would like the dynamic plot to look something like this:

enter image description here

the code for which is as follows:

Plot[{Sqrt[x]}, {x, 0, 10}, PlotRange -> {{0, 12}, {0, 3.5}},
Epilog -> {PointSize[Large], Red, Point[{4, 2}]}]

with the locator showing its coordinates as it is moved along the plot. Obviously, the movement of the locator needs to be constrained to the plot, just as it is constrained to the coordinates of the circle in this Wolfram Documentation example:

enter image description here

by the following code:

Deploy[DynamicModule[{p = {1, 0}}, Graphics[{Red, Disk[], 
Locator[Dynamic[p, (p = Normalize[#]) &]]}, PlotRange -> 1.5]]]

basically, so it behaves in a similar way to Google graphs:

enter image description here

where the coordinates appear to the top right of the plot.


@Timothy Wofford The solution you gave works great for functions like Sqrt[x], but runs into difficulties when complex values are encountered. For example:

enter image description here

generated by the code:

f[x_] := ((\[Pi]^x/Zeta[x])^(1/x)/\[Pi]) - 1/Zeta[x]
Manipulate[Plot[f[x], {x, 0, 10}, Epilog -> {PointSize[Large], Red, 
Tooltip[Point[#], #] &@{p[[1]], f[p[[1]]]}}, PlotLabel -> 
{p[[1]], f[p[[1]]]}], {{p, {1, 0}}, Locator, Appearance -> None}, 
AppearanceElements -> None]

shows as a red screen when the locator moves off screen into the imaginary values, generating an error screen as follows:

enter image description here

Is there any way of preventing this from happening? - ie, from stopping the locator moving past {1,0}?

  • 1
    $\begingroup$ I edited my answer to handle moving out of the domain of the function. p = {0, 0} is an example point for Sqrt (and really any {x,y} would work with x>0 as the y coordinate of the locator is not used). For your new function, p={x,y} where y is any value and x is in the domain of your new function. $\endgroup$ – Timothy Wofford Oct 19 '13 at 19:38
  • $\begingroup$ @ Timothy Wofford, Your fix works well for Sqrt[x], but still gives error as {0,Indeterminate} for above plot. Many thanks for your contributions though - they have been really helpful :-) $\endgroup$ – martin Oct 19 '13 at 22:58

Using another variable and Clip is easier than dealing with the second argument to Dynamic. Below I clipped the x coordinate of p to the plot domain, which won't let the red dot go beyond the ends of the curve. If you just want to stop it at 1, change the upper limit in Clip to Infinity. The clipped x coordinate is stored in x0 and inserted into the plot.

f[x_] := ((\[Pi]^x/Zeta[x])^(1/x)/\[Pi]) - 1/Zeta[x];
 With[{x0 = Clip[p[[1]], {1., 10. (* or Infinity *)}]},
  Plot[f[x], {x, 0, 10},
   Epilog -> {PointSize[Large], Red, 
     Tooltip[Point[#], #] &@{x0, f[x0]}}, PlotLabel -> {x0, f[x0]}]],
 {{p, {1, 0}}, Locator, Appearance -> None},
 AppearanceElements -> None]

One can use Dynamic, but you need to start the Manipulate body with your own LocatorPane. Something like

LocatorPane[Dynamic[p, (p = {#, f[#]} &@ Clip[#[[1]], {1., 10.}])&],

Declare the variable p as {{p, {1, 0}}, ControlType -> None}.

| improve this answer | |
  • $\begingroup$ @ Michael E2, Thank you very much - this is just what I was after. My next little project is to control 2 locators at once - is it appropriate to ask this as a new question, or to update this one? $\endgroup$ – martin Oct 19 '13 at 21:09
  • $\begingroup$ @ Michael E2, Your solution does provide the answer to my problem, but I was unsure that if I ticked it as the answer, whether my update would be looked at. Sorry - fairly new to this forum and am unsure whether I should post a new question, or just update this one. I will definitely be ticking your solution in due course though. $\endgroup$ – martin Oct 19 '13 at 21:30
  • $\begingroup$ Also, is it possible to format the coordinates(font colour, remove the curly brackets, etc.)? $\endgroup$ – martin Oct 19 '13 at 21:31
  • $\begingroup$ @martin I was just about to suggest, that the question of multiple locators probably ought to be a separate question. You might look at this question, too: mathematica.stackexchange.com/questions/22134/… $\endgroup$ – Michael E2 Oct 19 '13 at 21:33
  • $\begingroup$ Use Style to control font attributes. I think you have to construct parentheses manually: e.g., PlotLabel -> Style[Row[{"(", x0, ", ", f[x0], ")"}], Blue] $\endgroup$ – Michael E2 Oct 19 '13 at 21:43

The basic functionality is given by this.

f[x_] := Sqrt[x]
  Plot[f[x], {x, 0, 10}, 
    Epilog -> {PointSize[Large], Red, 
      Tooltip[Point[#], #]&@{p[[1]], f[p[[1]]]}},
    PlotLabel -> {p[[1]], f@p[[1]]}
  ],{{p, {0, 0}}, Locator, Appearance -> None}, 
 AppearanceElements -> None]

The locator is not actually constrained to the curve. Instead the locator has Appearance->None and we add a Point. The x coordinate of the point is given by the locator p[[1]] and the y coordinate is given by f@p[[1]].

I wrapped the built-in Tooltip around the point to display the coordinates. If you hover the mouse over the point, a tooltip will show the coordinates.

I wasn't sure if you wanted the coordinates displayed as in the Google example, so I added a PlotLabel as one way of displaying the coordinates.

For the Sqrt function, we assume x>0, but the user could drag the locator into the x<0 region. I'm not sure how to prevent that, but we can handle it.

  If[Im@f@p[[1]] != 0, p = {0, 0}];

Here, I check to see if the function returns a nonzero imaginary part, which used to cause the Plot to return an error. Now, we just move the locator back into the domain of the function.

| improve this answer | |
  • $\begingroup$ @ Timothy Wofford Great, thanks - perfect! I don't really understand the coding as yet - but I will work through it step by step - again, many thanks :-) $\endgroup$ – martin Oct 19 '13 at 18:58
  • $\begingroup$ @ Timothy Wofford The function I actually want to plot goes into imaginary values - is there any way of stopping the locator moving off screen & showing up as an error? $\endgroup$ – martin Oct 19 '13 at 19:09
  • 2
    $\begingroup$ Another way is If[Im@#[[2]] == 0, Tooltip[Point[#], #], Unevaluated@Sequence[]] & $\endgroup$ – ybeltukov Oct 19 '13 at 19:39
  • $\begingroup$ @ybeltukov, where did you come up with Unevaluated@Sequence[]? Having Sequence without any arguments isn't an example in the reference page. $\endgroup$ – Timothy Wofford Oct 19 '13 at 19:47
  • $\begingroup$ @ybeltukov, do you know of any way of preventing the error screen as illustrated above? $\endgroup$ – martin Oct 19 '13 at 19:52

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.