Skip to content

Instantly share code, notes, and snippets.

@ianhi
Forked from tacaswell/simp_zoom.py
Last active October 14, 2020 19:45
Show Gist options
  • Save ianhi/b638e09fa7a00764ea539940a0519af9 to your computer and use it in GitHub Desktop.
Save ianhi/b638e09fa7a00764ea539940a0519af9 to your computer and use it in GitHub Desktop.
factory for adding zoom callback to matplotlib imshow - now available via https://github.com/ianhi/mpl-interactions
import matplotlib.pyplot as plt
def zoom_factory(ax,base_scale = 1.1):
"""
parameters
----------
ax : matplotlib axes object
axis on which to implement scroll to zoom
base_scale : float
how much zoom on each tick of scroll wheel
returns
-------
disconnect_zoom : function
call this to disconnect the scroll listener
"""
def limits_to_range(lim):
return lim[1] - lim[0]
fig = ax.get_figure() # get the figure of interest
toolbar = fig.canvas.toolbar
toolbar.push_current()
orig_xlim = ax.get_xlim()
orig_ylim = ax.get_ylim()
orig_yrange = limits_to_range(orig_ylim)
orig_xrange = limits_to_range(orig_xlim)
orig_center = ((orig_xlim[0]+orig_xlim[1])/2, (orig_ylim[0]+orig_ylim[1])/2)
def zoom_fun(event):
# get the current x and y limits
cur_xlim = ax.get_xlim()
cur_ylim = ax.get_ylim()
# set the range
cur_xrange = (cur_xlim[1] - cur_xlim[0])*.5
cur_yrange = (cur_ylim[1] - cur_ylim[0])*.5
xdata = event.xdata # get event x location
ydata = event.ydata # get event y location
if event.button == 'up':
# deal with zoom in
scale_factor = base_scale
elif event.button == 'down':
# deal with zoom out
scale_factor = 1/base_scale
else:
# deal with something that should never happen
scale_factor = 1
# set new limits
new_xlim = [xdata - (xdata-cur_xlim[0]) / scale_factor,
xdata + (cur_xlim[1]-xdata) / scale_factor]
new_ylim = [ydata - (ydata-cur_ylim[0]) / scale_factor,
ydata + (cur_ylim[1]-ydata) / scale_factor]
new_yrange = limits_to_range(new_ylim)
new_xrange = limits_to_range(new_xlim)
if np.abs(new_yrange)>np.abs(orig_yrange):
new_ylim = orig_center[1] -new_yrange/2 , orig_center[1] +new_yrange/2
if np.abs(new_xrange)>np.abs(orig_xrange):
new_xlim = orig_center[0] -new_xrange/2 , orig_center[0] +new_xrange/2
ax.set_xlim(new_xlim)
ax.set_ylim(new_ylim)
toolbar.push_current()
ax.figure.canvas.draw_idle() # force re-draw
# attach the call back
cid = fig.canvas.mpl_connect('scroll_event',zoom_fun)
def disconnect_zoom():
fig.canvas.mpl_disconnect(cid)
#return the disconnect function
return disconnect_zoom
@ianhi
Copy link
Author

ianhi commented Jul 6, 2020

This fork adds on two things:

  1. Pushes initial position to toolbar so the home button will work
  2. If you zoom out past the initial bounds the image will be centered

@ianhi
Copy link
Author

ianhi commented Jul 6, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy