Greg814
Greg814

Reputation: 91

matplotlib: event handling and navigation for inset axes

In order to display one plot on top of another I can either

  1. use two axes and play with zorder
  2. or use inset axes instead
import matplotlib.pyplot as plt

fig = plt.figure()

ax0 = fig.add_axes([0.1,0.1,0.8,0.8], zorder=1)
ax0.set_title('ax0')

ax1 = fig.add_axes([0.175,0.5,0.3,0.3], zorder=2)
ax1.set_title('ax1')
ax1.set_facecolor('lightgray')
ax1.set_xlim(2,3)
ax1.set_ylim(2,3)

ax2 = ax0.inset_axes([0.575, 0.5, 0.375, 0.375])
ax2.set_title('ax2')
ax2.set_facecolor('gray')
ax2.set_xlim(4,5)
ax2.set_ylim(4,5)

plt.show()

Unfortunately, both options show erratic interaction behavior :

  1. ax1 does show the correct info in the navigation bar and allows for zoom/pan (good). However, the background axes ax0 is also zoomed and panned (not good).
  2. ax2 is completely ignored i.e. navbar info and zoom/pan only work for ax0

Question: Is there a simple way to disable info/zoom/pan for ax0 whenever the mouse event is inside ax1 or ax2 or do I have to go through the pain of overwriting event functions and doing coordinate transformations based on the bounding boxes of ax1/ax2, or even subclass the navigation bar?

PS: I only need either 1. or 2. to work, not both. 1. seems to be closer to the requested behavior to begin with if I could just switch off/on ax0 as I wish...

Upvotes: 1

Views: 429

Answers (2)

Greg814
Greg814

Reputation: 91

Diziet Asahi's answer connected to 'axes_enter_event' solves it for option 1. I couldn't make it work straightforward for inset axes. Also, zorder doesn't seem to be important now so it's removed.

Code for reference:

import matplotlib.pyplot as plt

fig = plt.figure()

ax0 = fig.add_axes([0.1,0.1,0.8,0.8])
ax0.set_title('ax0')

ax1 = fig.add_axes([0.175,0.5,0.3,0.3])
ax1.set_title('ax1')
ax1.set_facecolor('lightgray')
ax1.set_xlim(2,3)
ax1.set_ylim(2,3)

def enter_axes(event):
    if not event.inaxes:
        return
    if event.inaxes == ax1:
        ax0.set_navigate(False)
    elif event.inaxes == ax0:
        ax0.set_navigate(True)

fig.canvas.mpl_connect('axes_enter_event', enter_axes)

plt.show()

Upvotes: 2

Diziet Asahi
Diziet Asahi

Reputation: 40667

Simply use ax0.set_navigate(False) to stop ax0 from responding to navigation commands.

Upvotes: 2

Related Questions