14
14
You can copy and paste individual parts, or download the entire example
15
15
using the link at the bottom of the page.
16
16
"""
17
+
18
+ import functools
19
+
17
20
import matplotlib .pyplot as plt
18
21
import numpy as np
19
22
20
23
from matplotlib .patches import Rectangle
21
24
22
25
23
- # We just subclass Rectangle so that it can be called with an Axes
24
- # instance, causing the rectangle to update its shape to match the
25
- # bounds of the Axes
26
- class UpdatingRect (Rectangle ):
27
- def __call__ (self , ax ):
28
- self .set_bounds (* ax .viewLim .bounds )
29
- ax .figure .canvas .draw_idle ()
30
-
31
-
32
26
# A class that will regenerate a fractal set as we zoom in, so that you
33
27
# can actually see the increasing detail. A box in the left panel will show
34
28
# the area to which we are zoomed.
@@ -40,9 +34,9 @@ def __init__(self, h=500, w=500, niter=50, radius=2., power=2):
40
34
self .radius = radius
41
35
self .power = power
42
36
43
- def compute_image (self , xstart , xend , ystart , yend ):
44
- self .x = np .linspace (xstart , xend , self .width )
45
- self .y = np .linspace (ystart , yend , self .height ).reshape (- 1 , 1 )
37
+ def compute_image (self , xlim , ylim ):
38
+ self .x = np .linspace (* xlim , self .width )
39
+ self .y = np .linspace (* ylim , self .height ).reshape (- 1 , 1 )
46
40
c = self .x + 1.0j * self .y
47
41
threshold_time = np .zeros ((self .height , self .width ))
48
42
z = np .zeros (threshold_time .shape , dtype = complex )
@@ -56,38 +50,43 @@ def compute_image(self, xstart, xend, ystart, yend):
56
50
def ax_update (self , ax ):
57
51
ax .set_autoscale_on (False ) # Otherwise, infinite loop
58
52
# Get the number of points from the number of pixels in the window
59
- self .width , self .height = \
60
- np .round (ax .patch .get_window_extent ().size ).astype (int )
61
- # Get the range for the new area
62
- vl = ax .viewLim
63
- extent = vl .x0 , vl .x1 , vl .y0 , vl .y1
53
+ self .width , self .height = ax .patch .get_window_extent ().size .round ().astype (int )
64
54
# Update the image object with our new data and extent
65
- im = ax .images [- 1 ]
66
- im .set_data (self .compute_image (* extent ))
67
- im .set_extent (extent )
55
+ ax .images [- 1 ].set (data = self .compute_image (ax .get_xlim (), ax .get_ylim ()),
56
+ extent = (* ax .get_xlim (), * ax .get_ylim ()))
68
57
ax .figure .canvas .draw_idle ()
69
58
70
59
71
60
md = MandelbrotDisplay ()
72
- Z = md .compute_image (- 2. , 0.5 , - 1.25 , 1.25 )
73
-
74
- fig1 , (ax1 , ax2 ) = plt .subplots (1 , 2 )
75
- ax1 .imshow (Z , origin = 'lower' ,
76
- extent = (md .x .min (), md .x .max (), md .y .min (), md .y .max ()))
77
- ax2 .imshow (Z , origin = 'lower' ,
78
- extent = (md .x .min (), md .x .max (), md .y .min (), md .y .max ()))
79
-
80
- rect = UpdatingRect (
81
- [0 , 0 ], 0 , 0 , facecolor = 'none' , edgecolor = 'black' , linewidth = 1.0 )
82
- rect .set_bounds (* ax2 .viewLim .bounds )
83
- ax1 .add_patch (rect )
84
-
85
- # Connect for changing the view limits
86
- ax2 .callbacks .connect ('xlim_changed' , rect )
87
- ax2 .callbacks .connect ('ylim_changed' , rect )
88
-
89
- ax2 .callbacks .connect ('xlim_changed' , md .ax_update )
90
- ax2 .callbacks .connect ('ylim_changed' , md .ax_update )
91
- ax2 .set_title ("Zoom here" )
61
+
62
+ fig1 , (ax_full , ax_zoom ) = plt .subplots (1 , 2 )
63
+ ax_zoom .imshow ([[0 ]], origin = "lower" ) # Empty initial image.
64
+ ax_zoom .set_title ("Zoom here" )
65
+
66
+ rect = Rectangle (
67
+ [0 , 0 ], 0 , 0 , facecolor = "none" , edgecolor = "black" , linewidth = 1.0 )
68
+ ax_full .add_patch (rect )
69
+
70
+
71
+ def update_rect (rect , ax ): # Let the rectangle track the bounds of the zoom axes.
72
+ xlo , xhi = ax .get_xlim ()
73
+ ylo , yhi = ax .get_ylim ()
74
+ rect .set_bounds ((xlo , ylo , xhi - xlo , yhi - ylo ))
75
+ ax .figure .canvas .draw_idle ()
76
+
77
+
78
+ # Connect for changing the view limits.
79
+ ax_zoom .callbacks .connect ("xlim_changed" , functools .partial (update_rect , rect ))
80
+ ax_zoom .callbacks .connect ("ylim_changed" , functools .partial (update_rect , rect ))
81
+
82
+ ax_zoom .callbacks .connect ("xlim_changed" , md .ax_update )
83
+ ax_zoom .callbacks .connect ("ylim_changed" , md .ax_update )
84
+
85
+ # Initialize: trigger image computation by setting view limits; set colormap limits;
86
+ # copy image to full view.
87
+ ax_zoom .set (xlim = (- 2 , .5 ), ylim = (- 1.25 , 1.25 ))
88
+ im = ax_zoom .images [0 ]
89
+ ax_zoom .images [0 ].set (clim = (im .get_array ().min (), im .get_array ().max ()))
90
+ ax_full .imshow (im .get_array (), extent = im .get_extent (), origin = "lower" )
92
91
93
92
plt .show ()
0 commit comments