I am trying to have two panels, the left showing a graphic and two locators, the right one a zoomed-in version in the area defined by the locators.
I've tried
ClearAll[mndpt];
mndpt = Compile[{{c, _Complex}, {maxiter, _Integer}},
Module[{z, iters},
iters = 0.;
z = c;
While[(iters < maxiter) && (Abs@z < 2),
iters++;
z = z^2 + c];
Sqrt[iters/maxiter]],
{{z, _Complex}},
CompilationTarget \[Rule] "C",
RuntimeOptions \[Rule] "Speed"];
and do
Manipulate[
Grid[
{{DensityPlot[mndpt[x + y*I, 200],
{x, -2, 1}, {y, -1.5, 1.5},
PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80,
ColorFunction \[Rule] "Rainbow"],
DensityPlot[mndpt[x + y*I, 200],
Dynamic@{x, p1[[1]], p2[[1]]}, Dynamic@{y, p1[[2]], p2[[2]]},
PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80,
ColorFunction \[Rule] "Rainbow"]}}],
{{p1, {-1, -1}}, Locator}, {{p2, {0, 1}}, Locator}]
The right panel does not then work:
My question is, why is this so? As you can see, it complains that "DensityPlot::pllim: Range specification {x,-1,0} is not of the form {x, xmin, xmax}. " which I find puzzling. In fact I am generally puzzled. What is going on? Some sort of scoping issue? Evaluation issue? And how can I get it to work? This is probably simple, but I never really understood this frontend stuff.
EDIT: It turns out that this question was due to a (hopefully momentary) sharp increase in stupidity on my part. As pointed out by Simon in a comment, removing the two Dynamics
(which I had added in a blind effort to make this work) makes everything work fine. That is,
Manipulate[
Grid[
{{DensityPlot[mndpt[x + y*I, 200],
{x, -2, 1}, {y, -1.5, 1.5},
PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80,
ColorFunction \[Rule] "Rainbow"],
DensityPlot[mndpt[x + y*I, 200],
{x, p1[[1]], p2[[1]]},{y, p1[[2]], p2[[2]]},
PlotRange \[Rule] {0, 1}, PlotPoints \[Rule] 80,
ColorFunction \[Rule] "Rainbow"]}}],
{{p1, {-1, -1}}, Locator}, {{p2, {0, 1}}, Locator}]
does the right thing:
So, who knows why else I did the first few times so that it didn't work.
On the other hand, the message in the original case, namely, "DensityPlot::pllim: Range specification {x,-1,0} is not of the form {x, xmin, xmax}. " was more puzzling. I think it's been explained by Leonid, also in a comment (in brief, try ClearAttributes[Dynamic, ReadProtected]
then ??Dynamic
and you can see that there is a definition Dynamic/:MakeBoxes[BoxForm`x$_Dynamic,StandardForm]:=
etc). As my understanding of frontend programming is negligible I won't try to explain it here, so if anybody does post an answer explaining that, it would be appreciated.
As discussed in the comments to the question, the code works fine if the Dynamic
s are removed from the ranges in the second DensityPlot
. The Dynamic
s are not normally needed in the body of a Manipulate
as it is automatically wrapped in a dynamic construct. Although, for a more fine grained control of which parts of an expression update, it can be useful to use Dynamic
inside of a Manipulate
.
The reason an error was created was because the range of a plot should be of the form {x, xmin, xmax}
with x
a Symbol
and xmin
and xmax
numeric. Wrapping Dynamic
around the list changes the head and breaks the plot.
The reason that the error was not obvious to spot is because the error message was a little confusing:
Range specification {x,-1,0} is not of the form {x, xmin, xmax}.
Which, on the surface looks crazy, but makes sense once you realise (as pointed out by Leonid) that Dynamic
is a wrapper that has a MakeBoxes
definition that makes it invisible when outputted to the notebook. To see this, look at
In[1]:= FormatValues[Dynamic]
Out[1]= {HoldPattern[MakeBoxes[BoxForm`x$_Dynamic, StandardForm]] :> (DynamicModule;
DynamicDump`ControlToBoxes[BoxForm`x$, StandardForm]),
<<snip: same but for TraditionalForm>>}
and ControlToBoxes
in turn, creates a DynamicBox
object. This can also be seen by entering Dynamic[x]
and using the cell menu or shortcut to Show Expression of the produced output cell - you can also look at the underlying expression of the error message and see the DynamicBox
construction there. It's also possible to Unprotect
and remove the MakeBoxes
definition of Dynamic
, but that breaks most of the dynamic functionality in Mathematica...
Finally, here's my version of the code:
mndpt = Compile[{{c, _Complex}, {maxiter, _Integer}},
Module[{z = c, iters = 0.0},
While[(iters < maxiter) && (Abs@z < 2), iters++; z = z^2 + c];
Sqrt[iters/maxiter]], CompilationTarget -> "C",
RuntimeOptions -> "Speed"];
opts = Sequence[PlotPoints -> 80, ColorFunction -> "Rainbow",
ImageSize -> Medium, ImagePadding -> {{30, 5}, {20, 5}}];
fixed = DensityPlot[mndpt[x + y*I, 200], {x, -2, 1}, {y, -1.5, 1.5},
PlotPoints -> 120, Evaluate[opts]];
Manipulate[Grid[{{fixed, DensityPlot[mndpt[x + y*I, 200],
{x, p[[1, 1]], p[[2, 1]]}, {y, p[[1, 2]], p[[2, 2]]}, Evaluate[opts]]}}],
{{p, {{-1, -1}, {0, 1}}}, Locator, ContinuousAction -> False}]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With