17
$\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$
13
$\begingroup$

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

Button["Get x!", Print[FullForm@Setting@x]]
$\endgroup$
  • $\begingroup$ Great thanks! And sorry - I was looking for this sort of a function but I missed it - shame on me. $\endgroup$ – Marek Pfutzner Nov 23 '12 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$ – István Zachar Nov 23 '12 at 11:26
13
$\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, privacy policy and cookie policy

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