2 minutes
matplotlib: Interactively zooming to a subplot
I am using matplotlib a lot for my data analysis tasks and most things work as I expect them to do. One thing that I was missing so far for interactive use was the ability to focus an individual subplot and temporarily let it fill the whole screen for deeper inspection of this plot. In case of multiple subplots, with the standard GUI elements you can zoom and move around inside each subplot (without changing their geometry), but not focus one of them individually. Therefore I came up with the following solution:
def add_subplot_zoom(figure):
# temporary store for the currently zoomed axes. Use a list to work around
# python's scoping rules
zoomed_axes = [None]
def on_click(event):
ax = event.inaxes
if ax is None:
# occurs when a region not in an axis is clicked...
return
# we want to allow other navigation modes as well. Only act in case
# shift was pressed and the correct mouse button was used
if event.key != 'shift' or event.button != 1:
return
if zoomed_axes[0] is None:
# not zoomed so far. Perform zoom
# store the original position of the axes
zoomed_axes[0] = (ax, ax.get_position())
ax.set_position([0.1, 0.1, 0.85, 0.85])
# hide all the other axes...
for axis in event.canvas.figure.axes:
if axis is not ax:
axis.set_visible(False)
else:
# restore the original state
zoomed_axes[0][0].set_position(zoomed_axes[0][1])
zoomed_axes[0] = None
# make other axes visible again
for axis in event.canvas.figure.axes:
axis.set_visible(True)
# redraw to make changes visible.
event.canvas.draw()
figure.canvas.mpl_connect('button_press_event', on_click)
Applying this method to a figure will allow you to use Shift+Click
to let a single subplot fill the whole canvas and a second click of this kind will restore the original state.
This solution is partially based on the Stackoverflow question Matplotlib: Grab Single Subplot from Multiple Subplots but improves it for several corner cases.
Still some issues remain.
I couldn’t find out how to get the state of the usual navigation buttons in the event handler.
Therefore the code might interfere with the other navigation operations and also the home button might not work as expected.
In case someone find out, please let me know.