18
$\begingroup$

I want to inspect interactively an image by selecting points by the mouse pointer. This is easily done by LocatorPane - here is a simplified example:

plot = ListPlot[{{1, 1}}];
Manipulate[
  x = Dynamic[First[pt]];
  LocatorPane[Dynamic[pt], 
     Show[plot, Epilog -> {Red, PointSize[Large], Point[Dynamic[pt]],
     Text[Style[StringForm["x = `1`", x], Blue, 20], {1, 1.5}]}]],
  {{pt, {0, 0}}, None}
 ]

Mathematica graphics

Now imagine that for a selected point I would like to get the numerical value of the x-coordinate. I would like to calculate a function of it (like divide by 3) and/or save its numerical value to an external data file. This does not work because the x is a dynamical object. How to extract the current numerical value of x? In addition to solving this particular problem I would like to understand better how does Dynamic really work.

$\endgroup$

2 Answers 2

14
$\begingroup$

Use Setting: it replaces dynamic content (controllers, Dynamic objects, etc.) with its setting.

Button["Get x!", Print[FullForm@Setting@x]]
$\endgroup$
3
  • $\begingroup$ Great thanks! And sorry - I was looking for this sort of a function but I missed it - shame on me. $\endgroup$ Nov 23, 2012 at 11:22
  • $\begingroup$ @Marek I think it is an important question and I was surprised that it was never before asked here in Mathematica.SE. $\endgroup$ Nov 23, 2012 at 11:26
  • $\begingroup$ It doesn't works in version 12. $\endgroup$
    – matrix42
    Dec 10, 2021 at 3:00
14
$\begingroup$

I think @IstvanZachar's answer works fine but it's more complex than it seems at first sight, so don't take it lightly :P

It does something "smart" to leak a cell local variable pt to the outside. x is global and it stores the current name of the kernel's copy of the local pt, so you can access it from other cells.

An "easier" (conceptually) solution, that feels more natural to me is to simply not make pt local. Or, if you want the value of First@pt stored in x

plot = ListPlot[{{1, 1}}];
Manipulate[DynamicWrapper[
  LocatorPane[Dynamic[pt], 
   Show[plot, 
    Epilog -> {Red, PointSize[Large], Point[Dynamic[pt]], 
      Text[Style[StringForm["x = `1`", x], Blue, 20], {1, 1.5}]}]],
  x = First@pt], {{pt, {0, 0}}, None}]

and then just use x knowing it has the updated value and no Dynamic bothering

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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