2

I can't figure out why an expression isn't evaluating, even though there's no Hold* in its FullForm:

Plus[Dynamic[a$65712],Dynamic[Part[MousePosition[List["Graphics",Graphics],List[0,0]],1]]]

I've been stuck for hours now, and have gone through all kinds of threads including the one about Trott-Strzebonski and HoldCondition, but I'm afraid I may have missed the answer even if it was staring me in the face, due to lacking experience.

After reading How to | Evaluate Expressions inside Dynamic or Manipulate, I began to think it must have something to do with Dynamic or perhaps MousePosition, but my understanding is weak.

Here's the full code, before I continue explaining:

opts = {Axes -> False, Frame -> True, ImageSize -> {600, 400}, AspectRatio -> 1/GoldenRatio};
testdata1 = Table[{i, 5 Sin[i/10] + RandomReal[]}, {i, 100}];
testdata2 = {Log[#], #2} & @@@ testdata;
map1 = MapIndexed[Rule[testdata1[[First@#2, 1]], #] &, testdata2[[All, 1]]];
map2 = MapIndexed[Rule[testdata2[[First@#2, 1]], #] &, testdata1[[All, 1]]];
Deploy@DynamicModule[{x1, x2, a, b}, Column[{
    Graphics[{PointSize@Tiny, Point /@ testdata}, GridLines -> {{
        x1 = test1 = Dynamic[MousePosition[{"Graphics", Graphics}, {0, 0}][[1]]] + Dynamic[a];
        b = ((test2 = Nearest[map1[[All, 1]], x1]) /. map1)[[1, 1]];
        x1
    }, {}}, opts],
    Graphics[{PointSize@Tiny, Point /@ testdata2}, GridLines -> {{
        x2 = test3 = Dynamic[MousePosition[{"Graphics", Graphics}, {0, 0}][[1]]] + Dynamic[b];
        a = ((test4 = Nearest[map2[[All, 1]], x2]) /. map2)[[1, 1]];
        x2
    }, {}}, opts]
}]]

The line in question is this one:

        x1 = test1 = Dynamic[MousePosition[{"Graphics", Graphics}, {0, 0}][[1]]] + Dynamic[a];

Instead of adding up the two Dynamiced expressions, it's passing the held form to Nearest, which, of course, doesn't know what to do with such an input. That is, debug1 and debug2 output, respectively,

Plus[Dynamic[a$69525], Dynamic[Part[MousePosition[List["Graphics", Graphics], List[0, 0]], 1]]]

and

Nearest[{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,
61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,
91,92,93,94,95,96,97,98,99,100},1+0]

I'd greatly appreciate it if someone could point out where I went wrong.

Andrew Cheong
  • 3,576
  • 17
  • 42
  • 5
    Dynamic is used to dynamically display the value of its content. The result has a Dynamic head and can't be used for further calculation. If you want to do that you must place Dynamic outside of the Plus, not inside. – Sjoerd C. de Vries Oct 23 '13 at 11:22
  • 1
    Please read this and then these: (9550), (2972) – Mr.Wizard Oct 23 '13 at 13:12
  • I think the need for managing two separate Graphic spaces for the mouse events hasn't been answered before. Please check for it before voting to close – Dr. belisarius Oct 23 '13 at 15:10
  • @SjoerdC.deVries - Ah, I see, thanks. I recall wrapping the entire expression in a single Dynamic but it not working, and indeed I can't get it to work now either with just that change---I could be doing something else wrong as well. – Andrew Cheong Oct 24 '13 at 07:16
  • If you still have internal Dynamic functions that won't work. Remember, the result of a Dynamic is something visual, not something you can use to build calculations on. – Sjoerd C. de Vries Oct 24 '13 at 07:34
  • @Mr.Wizard - Thanks for your patience with me! I followed those links, tried out JohnFultz's examples, was enlightened, and examined Introduction to Dynamic more closely. (I only scanned it previously, assuming I'd understood Dynamic.) I think one sentence in the article is kinda misleading: "In fact it is generally the case that when you first evaluate an input that contains variables wrapped in Dynamic, you will get the same result as you would have without Dynamic." But later in the article, a section called "Where Should Dynamic Be Placed in an Expression?" explains it much better. – Andrew Cheong Oct 24 '13 at 07:37
  • Thanks, @SjoerdC.deVries. I'm only now getting used to that idea. I'd assumed (like an ass, yes) that Dynamic was something like bind or listeners in other languages, such that setting/getting from a variable (or all variables inside an expression) would trigger an event to update all other references. I think that was too naive an understanding, even if it's true to some degree as long as the result is displayed. – Andrew Cheong Oct 24 '13 at 07:41
  • @belisarius - Thanks for the defense. However I can see where others are coming from, if they are voting to close because this question arose from a misunderstanding of Dynamic, which had been covered in other threads. If this question does get closed/deleted, please feel free to add your answer to http://mathematica.stackexchange.com/questions/34434/hovering-mouse-cursor-over-a-plot-to-display-a-corresponding-point-in-another. Meanwhile, I'll link to this thread from there. – Andrew Cheong Oct 24 '13 at 08:03

1 Answers1

4
opts = {Axes -> False, Frame -> True, ImageSize -> {300, 200},  AspectRatio -> 1/GoldenRatio};
td1 = Table[{x, 5 Sin[x] + RandomReal[]}, {x, 1, 10, (10 - 1)/500}];
td2 = {Log[#], #2} & @@@ td1;
f = Nearest[td1 -> Automatic];
g = Nearest[td2 -> Automatic];
DynamicModule[{pt1 = {0, 0}, pt2 = {0, 0}, x1 = First@td1, x2 = First@td2},
 Row@{
   Deploy@EventHandler[Dynamic@
     Graphics[{Point@td1 , Red, PointSize[Large], Point[x1]}, opts, GridLines -> {{x1[[1]]}, {}}], 
     "MouseDown" :> ({x1, x2} = {td1[[#]], td2[[#]]} &@ f[MousePosition["Graphics"], 1])],
   Deploy@EventHandler[Dynamic@
   Graphics[{Point@td2, Green,  PointSize[Large], Point[x2]}, opts ,GridLines -> {{x2[[1]]}, {}}], 
     "MouseDown" :> ({x1, x2} = {td1[[#]], td2[[#]]} &@ g[MousePosition["Graphics"], 1])]
}]

enter image description here

Dr. belisarius
  • 115,881
  • 13
  • 203
  • 453
  • Thanks, @belisarius! I replaced the test data with my actual data (6,300 points, which caused problems with other solutions: http://mathematica.stackexchange.com/questions/34434/hovering-mouse-cursor-over-a-plot-to-display-a-corresponding-point-in-another) and the result displays immediately (and works great)! Do you think it'd break the interactive graphics if I tried to make the markers update on changes to MousePosition, rather than clicks? I guess we'll see! I'll give it a shot this weekend and report back here. Thanks again! – Andrew Cheong Oct 24 '13 at 07:56
  • Well, that was easy. Just replace the "MouseDown" event with "MouseMoved". Works like a charm, no lag! @belisarius, would you mind posting this answer in the other thread I linked, and deleting this answer here? I'll upvote and accept over there. It doesn't feel right to me that this question was more about the evaluation of expressions in Dynamic, which technically others answered in comments. – Andrew Cheong Oct 24 '13 at 08:29