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


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]];
    }, {}}, 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]];
    }, {}}, 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]]]



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

  • 5
    $\begingroup$ 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. $\endgroup$ Commented Oct 23, 2013 at 11:22
  • 1
    $\begingroup$ Please read this and then these: (9550), (2972) $\endgroup$
    – Mr.Wizard
    Commented Oct 23, 2013 at 13:12
  • $\begingroup$ 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 $\endgroup$ Commented Oct 23, 2013 at 15:10
  • $\begingroup$ @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. $\endgroup$ Commented Oct 24, 2013 at 7:16
  • $\begingroup$ 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. $\endgroup$ Commented Oct 24, 2013 at 7:34

1 Answer 1

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},
     Graphics[{Point@td1 , Red, PointSize[Large], Point[x1]}, opts, GridLines -> {{x1[[1]]}, {}}], 
     "MouseDown" :> ({x1, x2} = {td1[[#]], td2[[#]]} &@ f[MousePosition["Graphics"], 1])],
   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

  • $\begingroup$ Thanks, @belisarius! I replaced the test data with my actual data (6,300 points, which caused problems with other solutions: mathematica.stackexchange.com/questions/34434/…) 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! $\endgroup$ Commented Oct 24, 2013 at 7:56
  • $\begingroup$ 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. $\endgroup$ Commented Oct 24, 2013 at 8:29

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.