2
$\begingroup$

I want to make a series of plots, each of which will show a zoomed on region of the plot before.

So that everything is easy to understand, I want to mark the region which will be seen in the next plot by a dotted rectangle.

How can I draw this rectangle?

As an example: Say I want to plot sin(x), and then mark the region like in this picture here:

enter image description here

$\endgroup$
8
  • $\begingroup$ PlotRange to set the plot range, Epilog with Dashed and Rectangle to mark the region. Please look them up along with reference.wolfram.com/language/tutorial/… and related tutorials. $\endgroup$
    – Szabolcs
    May 31, 2019 at 21:25
  • 1
    $\begingroup$ Take a look at 140090, is this what you need? $\endgroup$
    – Kuba
    May 31, 2019 at 21:58
  • $\begingroup$ See also this mathematica.stackexchange.com/questions/195664/… $\endgroup$ Jun 1, 2019 at 10:02
  • $\begingroup$ @Szabolcs Thank you very much! This is what I needed. One follow up question: I now did it with Show and then Plot for the function plot on the one hand, and Graphics + Rectangle for the region on the other hand. What is the benefit by doing it with Epilog instead of Show? $\endgroup$
    – Britzel
    Jun 3, 2019 at 18:25
  • $\begingroup$ @Kuba This is actually even more advanced! So far I am happy with only marking the region, and then make a second plot for the zoomed in part. But I will keep this in mind for the future to make even nicer plots. Thanks for linking! $\endgroup$
    – Britzel
    Jun 3, 2019 at 18:26

1 Answer 1

6
$\begingroup$

Using a combination of Epilog, Rectangle and Locator in a DynamicModule:

plt = Plot[ Cos[ 3 Sin[2 x] x] x, {x, -2 Pi, 2 Pi}, AspectRatio -> Automatic];

DynamicModule[{pts = {{-3, -3}, {4, 3}}}, 
 Show[plt, 
  Epilog -> Dynamic @ {Directive[EdgeForm[{Red, Dashed}], Lighter@Yellow, Opacity[.3]],
     Dynamic[Rectangle @@ pts], 
     MapThread[Locator[Dynamic[pts[[#]]], 
        Graphics[{#2, Rectangle[]}, ImageSize -> 8], 
        LocatorRegion -> Full] &, {{1, 2}, {Black, Gray}}]}]]

enter image description here

Alternatively define a function zoom to define a rectangle with interactively adjustable coordinates:

ClearAll[zoom]
zoom[Dynamic[coords_], edgestyle_: Orange, facestyle_: LightYellow] :=
  Graphics[{Directive[EdgeForm[{edgestyle, Dashed}], facestyle, Opacity[.3]], 
   Dynamic[Rectangle @@ coords], 
   MapThread[Locator[Dynamic[coords[[#]]], 
        Graphics[{#2, Rectangle[]}, ImageSize -> 8], LocatorRegion -> Full] &,
     {{1, 2}, {Black, Gray}}]}]

You can use zoom with a single plot:

DynamicModule[{pts = Transpose @ PlotRange[plt]/2}, 
 Show[plt, zoom[Dynamic @ pts, Red, Lighter @ Lighter @ Red]]]

enter image description here

To get a series of plots each zooming on a region of the previous one, we can use zoom as a helper function as follows:

ClearAll[shrink, paneled, zoompanels]
shrink[s_] := {##} + {-1, 1} s Subtract[##]/2 &;

paneled = Panel[#, ImageSize -> {300, 300}, Alignment -> Center] &;

zoompanels[plt_, sh_: .25] := DynamicModule[{pta = Transpose[PlotRange[plt]], 
   ptb = Transpose[shrink[sh] @@@ PlotRange[plt]]}, 
  Row[paneled /@ {Show[plt, zoom[Dynamic[pta]]], 
    ptb = Transpose[shrink[sh] @@@ Transpose[pta]]; 
   Framed[Show[plt, zoom[Dynamic[ptb], Blue, LightBlue],
     PlotRange -> Dynamic[Transpose[pta]]], FrameStyle -> Orange], 
   Framed[Show[ plt, PlotRange -> Dynamic[Transpose[ptb]]], 
     FrameStyle -> Blue]}]]

Using zoompanels to create cascading zooms:

Deploy @ zoompanels[plt]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.