When trying to make an optimized version of my plotRange function I faced a problem of catching the "Preemptive" evaluations generated by the FrontEnd from withing the main evaluation loop.

Consider the following:

xr[r__] := (xRange = {r}; None);
yr[r__] := (yRange = {r}; None);
nb = CreateDocument[{Plot[Sin[x], {x, 0, 6 Pi}, Ticks -> {xr, yr}]}];
{xRange, yRange}
{xRange, yRange}

{xRange, yRange}

{{-0.392699, 19.2423}, {-1.04167, 1.04167}}

One can see that the first evaluation of {xRange, yRange} returns undefined symbols because at the moment of its evaluation the functions xr and yr are still not evaluated via a "Preemptive" link by the FrontEnd. But after waiting one second these functions are already evaluated and xRange, yRange are defined. Because I need these values for further evaluations I need to delay the main loop until the "Preemptive" evaluations will be done. (An alternative solution would be to force the FrontEnd to perform its evaluations in the main loop.)

One possible way to solve the problem is to initiate a Dialog which will wait for the Return generated by the FrontEnd. But "Preemptive" evaluations go past the Dialog and do not allow the return from it (the following code freezes the kernel):

Dialog[xr[r__] := (xRange = {r}; None);
 yr[r__] := (yRange = {r}; None; NotebookClose[nb]; 
   Return[{xRange, yRange}]);
 nb = CreateDocument[{Plot[Sin[x], {x, 0, 6 Pi}, 
     Ticks -> {xr, yr}]}];]

Is it possible to catch the "Preemptive" evaluations from the main loop in some way?


Here is a comparison of my original Rasterize-based version and the new FinishDynamic-based:

gr = Plot[Sin[x], {x, 0, 6 Pi}];
plotRange[plot : (_Graphics | _Graphics3D)] := 
      Show[plot, PlotRangePadding -> None, Axes -> True, 
       Ticks -> (Sow[{##}] &), DisplayFunction -> Identity], 
      ImageResolution -> 1]]
Table[plotRange[gr], {100}]; // AbsoluteTiming

plotRange[plot : (_Graphics | _Graphics3D)] := 
   Last@Reap[(nb = 
       CreateDocument[{Show[plot, Axes -> True, 
          Ticks -> (Sow[{##}] &), PlotRangePadding -> None, 
          DisplayFunction -> Identity]}, ShowCellBracket -> False, 
        WindowFrame -> "Frameless", WindowElements -> {}, 
        WindowSize -> 1, Antialiasing -> False, Editable -> False, 
        Magnification -> 1, Saveable -> False, 
        WindowClickSelect -> False, WindowFloating -> False, 
        WindowFrameElements -> {}, WindowMovable -> False, 
        WindowSelected -> False, WindowTitle -> ""];
      FinishDynamic[]; NotebookClose[nb])]
Table[plotRange[gr], {100}]; // AbsoluteTiming

{2.828125, Null}

{8.406250, Null}

The original Rasterize-based version is 3 times faster.

  • $\begingroup$ I got {{-0.392699, 19.2423}, {-1.04167, 1.04167}} from both of the two evaluations. My system: v9 on win7 64bit. $\endgroup$
    – Silvia
    Jan 24, 2013 at 0:17
  • 1
    $\begingroup$ I reproduced it in v9 on Windows, but failed to reproduce it on my Macbook Air. But this behavior depends upon the ordering of Dynamic evaluations. Those orderings are specifically not guaranteed by Mathematica. $\endgroup$
    – John Fultz
    Jan 24, 2013 at 11:21
  • $\begingroup$ @JohnFultz Does it mean that the code Reap[Rasterize[Show[plot, Ticks -> (Sow[{##}] &)]]][[2, 1]] do not guarantee that the ordering of ranges will always be standard: {xRange, yRange} and sometimes one can get {yRange, xRange}? $\endgroup$ Jan 25, 2013 at 13:29
  • 1
    $\begingroup$ @AlexeyPopkov No, I mean that the evaluation of the Ticks function, which is acting like a Dynamic in this case (even though no Dynamic was specified, it's resolved in a similar fashion), might be evaluated at any time relative to the ordering of the Shift+Enter evaluations. It might happen before the CreateDocument has finished evaluation, or shortly thereafter, or a very long time thereafter. That's why it behaves differently on different machines...because there is no guarantee...it's just evaluating when it can. $\endgroup$
    – John Fultz
    Jan 31, 2013 at 8:31

1 Answer 1


After the dynamic evaluation (in this case, your plot) has been displayed to the screen but before you wish to access the variables, evaluate:


Note that this function isn't selective. It will force every Dynamic in the entire system to update before it continues.


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.