Skip to content

Commit c287b9f

Browse files
authored
Merge pull request matplotlib#27594 from anntzer/vl
Cleanup viewlims example.
2 parents 3a2a9d9 + f8cd003 commit c287b9f

File tree

1 file changed

+39
-40
lines changed

1 file changed

+39
-40
lines changed

galleries/examples/event_handling/viewlims.py

+39-40
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,15 @@
1414
You can copy and paste individual parts, or download the entire example
1515
using the link at the bottom of the page.
1616
"""
17+
18+
import functools
19+
1720
import matplotlib.pyplot as plt
1821
import numpy as np
1922

2023
from matplotlib.patches import Rectangle
2124

2225

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-
3226
# A class that will regenerate a fractal set as we zoom in, so that you
3327
# can actually see the increasing detail. A box in the left panel will show
3428
# the area to which we are zoomed.
@@ -40,9 +34,9 @@ def __init__(self, h=500, w=500, niter=50, radius=2., power=2):
4034
self.radius = radius
4135
self.power = power
4236

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)
4640
c = self.x + 1.0j * self.y
4741
threshold_time = np.zeros((self.height, self.width))
4842
z = np.zeros(threshold_time.shape, dtype=complex)
@@ -56,38 +50,43 @@ def compute_image(self, xstart, xend, ystart, yend):
5650
def ax_update(self, ax):
5751
ax.set_autoscale_on(False) # Otherwise, infinite loop
5852
# 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)
6454
# 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()))
6857
ax.figure.canvas.draw_idle()
6958

7059

7160
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")
9291

9392
plt.show()

0 commit comments

Comments
 (0)