2

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

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
Britzel
  • 663
  • 3
  • 10
  • PlotRange to set the plot range, Epilog with Dashed and Rectangle to mark the region. Please look them up along with http://reference.wolfram.com/language/tutorial/TheStructureOfGraphics.html and related tutorials. – Szabolcs May 31 '19 at 21:25
  • 1
    Take a look at 140090, is this what you need? – Kuba May 31 '19 at 21:58
  • See also this https://mathematica.stackexchange.com/questions/195664/plotting-a-graph-of-a-function-and-part-of-it/195675#195675 – OkkesDulgerci Jun 01 '19 at 10:02
  • @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? – Britzel Jun 03 '19 at 18:25
  • @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! – Britzel Jun 03 '19 at 18:26
  • @OkkesDulgerci 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! – Britzel Jun 03 '19 at 18:26
  • I think Show is fine here (either is fine). – Szabolcs Jun 03 '19 at 21:57
  • Thanks @Szabolcs ! – Britzel Jun 07 '19 at 13:58

1 Answers1

8

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

kglr
  • 394,356
  • 18
  • 477
  • 896