Skip to main content

dynamic - Using Refresh[..] with TrackedSymbols


This is a very basic question, but I don't understand the following behavior. The usage to Refresh reads




represents an object whose value in a Dynamic should be refreshed at times specified by the options opts.



Although the word times was mentioned explicitly the examples suggest, that Refresh can also be used to restrict the TrackedSymbols in an expression inside Dynamic. Here is a basic example from the help, which works like a charm


Manipulate[
{x, Refresh[y, TrackedSymbols :> {x}]},
{x, 0, 1},
{y, 0, 1}
]

Mathematica graphics



When you move the y-slider, nothing happens because the second expression containing y is restricted to keep only track of x. When you then move x, the y values jumps to it's current value.


Now, let's extend this example a bit


Manipulate[
{Refresh[{x, y}, TrackedSymbols :> {y}],
Refresh[{x, y}, TrackedSymbols :> {x}]},
{x, 0, 1},
{y, 0, 1}
]

What I had hoped for was, that when I move the x-slider, only the x-value in the second {x,y} is updated because the first {x,y} tracks only y. Equivalent for the y-slider. Unfortunately, all values are always updated.



Solutions to this is can be found at the end of the post, but first my question:


Can someone explain what I have missed in the documentation of Refresh and how this is supposed to be used?


Several solutions to the toy-example can be found. The most prominent one is to wrap each Refresh in Dynamic


Manipulate[{
Dynamic@Refresh[{x, y}, TrackedSymbols :> {y}],
Dynamic@Refresh[{x, y}, TrackedSymbols :> {x}]},
{x, 0, 1},
{y, 0, 1}
]


This goes along with the suggestion of andre's answer, when I understood him right.


Further solutions are


Manipulate[
{Dynamic[{x, y}, TrackedSymbols :> {y}],
Dynamic[{x, y}, TrackedSymbols :> {x}]},
{x, 0, 1},
{y, 0, 1}
]

DynamicModule[{},

Column@{Dynamic[{x, y}, TrackedSymbols :> {y}],
Dynamic[{x, y}, TrackedSymbols :> {x}],
Slider[Dynamic[x]],
Slider[Dynamic[y]]
}]


DynamicModule[{},
Column@{Dynamic@Refresh[{x, y}, TrackedSymbols :> {y}],
Dynamic@Refresh[{x, y}, TrackedSymbols :> {x}],

Slider[Dynamic[x]],
Slider[Dynamic[y]]
}]

This leaves the question, when I have to use Dynamic anyway, why does the documentation suggest Refresh can do this alone. I still think I'm missing something.



Answer



I think I have to explain how I look at Dynamic before I can speak about Refresh.


Dynamic is the basic element of dynamic updating, and the only one as far as I can tell. Anything that behaves dynamically has Dynamic somewhere inside it, I believe.


If you think of an expression as a tree, then Dynamic[code] marks out the branch representing code for dynamic updating. An update can occur only if code evaluates to something visible in the front end. The whole branch will be reevaluated when an update occurs -- even the invisible parts if code is, say, a CompoundExpression.


By default, an update occurs any time one or more of the symbols in code changes value. Refresh can be used to restrict when updating occurs through the TrackedSymbols option. (It can also cause updates that depend only on time through the UpdateInterval option.) TrackedSymbols does not make an expression depend on symbols it does not contain; rather, the dependence will be on the intersection of the symbols in code and in the TrackedSymbols list.



Refresh always needs a surrounding Dynamic for updates to occur. Manipulate does this automatically, so Refresh by itself inside a Manipulate will have an effect. See, for instance, Advanced Manipulate Functionality:



In reading those, keep in mind that Manipulate simply wraps its first argument in Dynamic and passes the value of its TrackedSymbols option to a Refresh inside that.



See also the section on Refresh in Advanced Dynamic Functionality. These expand the cryptic explanation from the manual page:



When Refresh[expr,opts] is evaluated inside a Dynamic, it gives the current value of expr, then specifies criteria for when the Dynamic should be updated.





As a first example, consider



DynamicModule[{x, y},
Column[{
{x,
Dynamic[{x,
Dynamic@Refresh[{x, y}, TrackedSymbols :> {y}]}],
Dynamic@Refresh[{x, y}, TrackedSymbols :> {y}]},

Slider[Dynamic[x]],
Slider[Dynamic[y]]
}]

]

The main expression to consider is


{x, 
Dynamic[{x,
Dynamic[{x, y}, TrackedSymbols :> {y}]}],
Dynamic[{x, y}, TrackedSymbols :> {y}]}

Note that two of the subexpressions look the same. I might represent it as a tree thus:


Tree diagram of the code show the dynamic sub-branches



The frames on the branches represent Dynamic wrappers, and the tracked symbols are in the upper left corner.


When the slider for x is moved, dynamic expressions depending on x are reevaluated (in the kernel) and updated (in the front end). Only the middle one is dynamic and depends on x. The first x is never even initialized (see note* below), and it never changes.


When the slider for y is moved, dynamic expressions depending on y are reevaluated and updated. These are the last two. The middle one has an interior Dynamic that depends on y (only), which would seem to make the whole middle Dynamic depend on y, too; however, it is wrapped in Dynamic so changes to y only affect that branch. (Mathematica will updated the smallest branch necessary.) [Thanks to @andre for pointing out a mistake in the previous explanation.]


There is a curious difference between the middle and last expressions. The two Dynamic@Refresh.. expressions look identical but they do not behave the same. When x is changed, the one inside the middle updates its display, but the one at the end does not. The reason is the outer Dynamic in the middle depends on x. It reevaluates its expression when x changes, including evaluating the Dynamic@Refresh that is a part of the expression.


(*In fact, the first x is never even mapped to a front end context symbol, something like FE`x$$14. It displays as simply x$$. The other x in the expression are in a Dynamic and they get renamed to something like FE`x$$14. Try DynamicModule[{x, y}, {x, Dynamic[Hold[x]]}] and see.)




Analysis of a couple of @halirutan's examples.


A. This one


Manipulate[
{x, Refresh[y, TrackedSymbols :> {x}]},

{x, 0, 1}, {y, 0, 1}]

is equivalent to


Dynamic@Refresh[{x, Refresh[y, TrackedSymbols :> {x}]}, 
TrackedSymbols :> {x, y}]

The main expression, {x,Refresh[y,TrackedSymbols:>{x}]}, depends only on x: Refresh limits the expression y to depend on the symbols in the tracked symbols list that occur in the expression. So it can depend only on x, but no x appears in y. Therefore the Refresh does not depend on any symbol and will not generate an update. In all then, the main expression depends only on x.


So it is not updated when y changes, only when x changes.


B. And this one


Manipulate[

{Refresh[{x, y}, TrackedSymbols :> {y}],
Refresh[{x, y}, TrackedSymbols :> {x}]},
{x, 0, 1}, {y, 0, 1}]

is equivalent to


Dynamic@Refresh[
{Refresh[{x, y}, TrackedSymbols :> {y}],
Refresh[{x, y}, TrackedSymbols :> {x}]},
TrackedSymbols :> {x, y}]


Again there is only one Dynamic. Since only subexpressions inside a Dynamic are updated and like above the single Dynamic contains everything, then everything will be updated or nothing will be. The first Refresh depends on y and the second on x; thus together, the whole depends on both x and y. Therefore it is updated whenever x or y changes.


Comments

Popular posts from this blog

plotting - Plot 4D data with color as 4th dimension

I have a list of 4D data (x position, y position, amplitude, wavelength). I want to plot x, y, and amplitude on a 3D plot and have the color of the points correspond to the wavelength. I have seen many examples using functions to define color but my wavelength cannot be expressed by an analytic function. Is there a simple way to do this? Answer Here a another possible way to visualize 4D data: data = Flatten[Table[{x, y, x^2 + y^2, Sin[x - y]}, {x, -Pi, Pi,Pi/10}, {y,-Pi,Pi, Pi/10}], 1]; You can use the function Point along with VertexColors . Now the points are places using the first three elements and the color is determined by the fourth. In this case I used Hue, but you can use whatever you prefer. Graphics3D[ Point[data[[All, 1 ;; 3]], VertexColors -> Hue /@ data[[All, 4]]], Axes -> True, BoxRatios -> {1, 1, 1/GoldenRatio}]

plotting - Filling between two spheres in SphericalPlot3D

Manipulate[ SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, Mesh -> None, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], {n, 0, 1}] I cant' seem to be able to make a filling between two spheres. I've already tried the obvious Filling -> {1 -> {2}} but Mathematica doesn't seem to like that option. Is there any easy way around this or ... Answer There is no built-in filling in SphericalPlot3D . One option is to use ParametricPlot3D to draw the surfaces between the two shells: Manipulate[ Show[SphericalPlot3D[{1, 2 - n}, {θ, 0, Pi}, {ϕ, 0, 1.5 Pi}, PlotPoints -> 15, PlotRange -> {-2.2, 2.2}], ParametricPlot3D[{ r {Sin[t] Cos[1.5 Pi], Sin[t] Sin[1.5 Pi], Cos[t]}, r {Sin[t] Cos[0 Pi], Sin[t] Sin[0 Pi], Cos[t]}}, {r, 1, 2 - n}, {t, 0, Pi}, PlotStyle -> Yellow, Mesh -> {2, 15}]], {n, 0, 1}]

plotting - Mathematica: 3D plot based on combined 2D graphs

I have several sigmoidal fits to 3 different datasets, with mean fit predictions plus the 95% confidence limits (not symmetrical around the mean) and the actual data. I would now like to show these different 2D plots projected in 3D as in but then using proper perspective. In the link here they give some solutions to combine the plots using isometric perspective, but I would like to use proper 3 point perspective. Any thoughts? Also any way to show the mean points per time point for each series plus or minus the standard error on the mean would be cool too, either using points+vertical bars, or using spheres plus tubes. Below are some test data and the fit function I am using. Note that I am working on a logit(proportion) scale and that the final vertical scale is Log10(percentage). (* some test data *) data = Table[Null, {i, 4}]; data[[1]] = {{1, -5.8}, {2, -5.4}, {3, -0.8}, {4, -0.2}, {5, 4.6}, {1, -6.4}, {2, -5.6}, {3, -0.7}, {4, 0.04}, {5, 1.0}, {1, -6.8}, {2, -4.7}, {3, -1....