8000 Cleanup viewlims example. by anntzer · Pull Request #27594 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content
8000

Cleanup viewlims example. #27594

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 4, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 39 additions & 40 deletions galleries/examples/event_handling/viewlims.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,15 @@
You can copy and paste individual parts, or download the entire example
using the link at the bottom of the page.
"""

import functools

import matp 10000 lotlib.pyplot as plt
import numpy as np

from matplotlib.patches import Rectangle


# We just subclass Rectangle so that it can be called with an Axes
# instance, causing the rectangle to update its shape to match the
# bounds of the Axes
class UpdatingRect(Rectangle):
def __call__(self, ax):
self.set_bounds(*ax.viewLim.bounds)
ax.figure.canvas.draw_idle()


# A class that will regenerate a fractal set as we zoom in, so that you
# can actually see the increasing detail. A box in the left panel will show
# the area to which we are zoomed.
Expand All @@ -40,9 +34,9 @@ def __init__(self, h=500, w=500, niter=50, radius=2., power=2):
self.radius = radius
self.power = power

def compute_image(self, xstart, xend, ystart, yend):
self.x = np.linspace(xstart, xend, self.width)
self.y = np.linspace(ystart, yend, self.height).reshape(-1, 1)
def compute_image(self, xlim, ylim):
self.x = np.linspace(*xlim, self.width)
self.y = np.linspace(*ylim, self.height).reshape(-1, 1)
c = self.x + 1.0j * self.y
threshold_time = np.zeros((self.height, self.width))
z = np.zeros(threshold_time.shape, dtype=complex)
Expand All @@ -56,38 +50,43 @@ def compute_image(self, xstart, xend, ystart, yend):
def ax_update(self, ax):
ax.set_autoscale_on(False) # Otherwise, infinite loop
# Get the number of points from the number of pixels in the window
self.width, self.height = \
np.round(ax.patch.get_window_extent().size).astype(int)
# Get the range for the new area
vl = ax.viewLim
extent = vl.x0, vl.x1, vl.y0, vl.y1
self.width, self.height = ax.patch.get_window_extent().size.round().astype(int)
# Update the image object with our new data and extent
im = ax.images[-1]
im.set_data(self.compute_image(*extent))
im.set_extent(extent)
ax.images[-1].set(data=self.compute_image(ax.get_xlim(), ax.get_ylim()),
extent=(*ax.get_xlim(), *ax.get_ylim()))
ax.figure.canvas.draw_idle()


md = MandelbrotDisplay()
Z = md.compute_image(-2., 0.5, -1.25, 1.25)

fig1, (ax1, ax2) = plt.subplots(1, 2)
ax1.imshow(Z, origin='lower',
extent=(md.x.min(), md.x.max(), md.y.min(), md.y.max()))
ax2.imshow(Z, origin='lower',
extent=(md.x.min(), md.x.max(), md.y.min(), md.y.max()))

rect = UpdatingRect(
[0, 0], 0, 0, facecolor='none', edgecolor='black', linewidth=1.0)
rect.set_bounds(*ax2.viewLim.bounds)
ax1.add_patch(rect)

# Connect for changing the view limits
ax2.callbacks.connect('xlim_changed', rect)
ax2.callbacks.connect('ylim_changed', rect)

ax2.callbacks.connect('xlim_changed', md.ax_update)
ax2.callbacks.connect('ylim_changed', md.ax_update)
ax2.set_title("Zoom here")

fig1, (ax_full, ax_zoom) = plt.subplots(1, 2)
ax_zoom.imshow([[0]], origin="lower") # Empty initial image.
ax_zoom.set_title("Zoom here")

rect = Rectangle(
[0, 0], 0, 0, facecolor="none", edgecolor="black", linewidth=1.0)
ax_full.add_patch(rect)


def update_rect(rect, ax): # Let the rectangle track the bounds of the zoom axes.
xlo, xhi = ax.get_xlim()
ylo, yhi = ax.get_ylim()
rect.set_bounds((xlo, ylo, xhi - xlo, yhi - ylo))
ax.figure.canvas.draw_idle()


# Connect for changing the view limits.
ax_zoom.callbacks.connect("xlim_changed", functools.partial(update_rect, rect))
ax_zoom.callbacks.connect("ylim_changed", functools.partial(update_rect, rect))

ax_zoom.callbacks.connect("xlim_changed", md.ax_update)
ax_zoom.callbacks.connect("ylim_changed", md.ax_update)

# Initialize: trigger image computation by setting view limits; set colormap limits;
# copy image to full view.
ax_zoom.set(xlim=(-2, .5), ylim=(-1.25, 1.25))
im = ax_zoom.images[0]
ax_zoom.images[0].set(clim=(im.get_array().min(), im.get_array().max()))
ax_full.imshow(im.get_array(), extent=im.get_extent(), origin="lower")

plt.show()
0