Convert Dynamic [] construct to a numerical list

I am trying to collect something that allows me to extract points from a ListPlot so that I can use them in further calculations. My current approach is to select points using Locator []. This is great for displaying points, but I can't figure out how to extract numerical values ​​from a construct using the Dynamic [] chapter. Below is a self-sufficient example. By dragging the gray locator, you can select the points (indicated by the pink locator and saved in q , a list of two elements). This is the second line below the graph. Now I would like to pass q [[2]] to the function, or maybe just display it. However, Mathematica regards q as a single entity with the Dynamic head, and therefore the second part is impossible (hence the error message). Can anyone shed some light on how to convert q to a regular list?

 EuclideanDistanceMod[p1_List, p2_List, fac_: {1, 1}] /; Length[p1] == Length[p2] := Plus @@ (fac.MapThread[Abs[#1 - #2]^2 &, {p1, p2}]) // Sqrt; test1 = {{1.`, 6.340196001221532`}, {1.`, 13.78779876355869`}, {1.045`, 6.2634018978377295`}, {1.045`, 13.754947081416544`}, {1.09`, 6.178367702583522`}, {1.09`, 13.72055251752498`}, {1.135`, 1.8183153704413153`}, {1.135`, 6.082497198000075`}, {1.135`, 13.684582525399742`}, {1.18`, 1.6809452373465104`}, {1.18`, 5.971583107298081`}, {1.18`, 13.646996905469383`}, {1.225`, 1.9480537697339537`}, {1.225`, 5.838386922625636`}, {1.225`, 13.607746407088161`}, {1.27`, 2.1183174369679234`}, {1.27`, 5.669799095595362`}, {1.27`, 13.566771130126131`}, {1.315`, 2.2572975468163463`}, {1.315`, 5.444014254828522`}, {1.315`, 13.523998701347882`}, {1.36`, 2.380307009155079`}, {1.36`, 5.153024664297602`}, {1.36`, 13.479342200528283`}, {1.405`, 2.4941312539733285`}, {1.405`, 4.861423833512566`}, {1.405`, 13.432697814928654`}, {1.45`, 2.6028066447609426`}, {1.45`, 4.619367407525507`}, {1.45`, 13.383942212133244`}}; DynamicModule[{p = {1.2, 10}, q = {1.3, 11}}, q := Dynamic@ First@test1[[ Ordering[{#, EuclideanDistanceMod[p, #, {1, .1}]} & /@ test1, 1, #1[[2]] < #2[[2]] &]]]; Grid[{{Show[{ListPlot[test1, Frame -> True, ImageSize -> 300], Graphics@Locator[Dynamic[p]], Graphics@ Locator[q, Appearance -> {Small}, Background -> Pink]}]}, {Dynamic@p}, {q},{q[[2]]}}]] 
+7
dynamic wolfram-mathematica
source share
2 answers

After a bit of research, it turned out that the answer revolves around the fact that Dynamic [] is a wrapper for updating and displaying an expression. Any calculations that you want to dynamically update should be placed inside the shell: for example, instead of doing something like q = Dynamic[p] + 1 , you need to use something like Dynamic[q = p + 1; q]}] Dynamic[q = p + 1; q]}] . For my example, where I wanted to split q into two parts, here is the updated code:

 DynamicModule[{p = {1.2, 10}, q = {1.3, 11}, qq, q1, q2}, q := Dynamic[ qq = First@ test1[[Ordering[{#, EuclideanDistanceMod[p, #, {1, .1}]} & /@ test1, 1, #1[[2]] < #2[[2]] &]]]; {q1, q2} = qq; qq ]; Grid[{{Show[{ListPlot[test1, Frame -> True, ImageSize -> 300], Graphics@Locator[Dynamic[p]], Graphics@ Locator[q, Appearance -> {Small}, Background -> Pink]}]}, {Dynamic@p}, {Dynamic@q}, {Dynamic@ q1}}]] 

If I still miss something, or if there is a cleaner way to do it, I welcome any suggestions ...

+2
source share

There are several ways to extract values ​​from a dynamic expression. You might want Setting (documentation) , which resolves all dynamic values ​​to their values ​​at the time Setting .

 In[75]:= Slider[Dynamic[x]] (* evaluate then move the slider *) In[76]:= FullForm[Dynamic[x]] Out[76]//FullForm= Dynamic[x] In[77]:= FullForm[Setting[Dynamic[x]]] Out[77]//FullForm= 0.384` 

Here is a slightly more complex example:

 DynamicModule[{x}, {Dynamic[x], Slider[Dynamic[x]], Button["Set y to the current value of x", y = Setting[Dynamic[x]]]} ] 

If you evaluate the above expression, move the slider, and then press the button, the current x value set by the slider is assigned y . If you move the slider again, the y value will not change until you refresh it again by pressing the button.

Instead of assigning a variable, you can paste values ​​into a notepad, call a function, export a file, etc.

+5
source share

All Articles