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

Already on GitHub? Sign in to your account

twinx() on an inset axes wrongly acts on the main axes #1499

phobson opened this Issue Nov 14, 2012 · 3 comments


None yet
3 participants

phobson commented Nov 14, 2012

Seen here:

On version 1.2.0, this is all fine and dandy:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes
from mpl_toolkits.axes_grid1.inset_locator import mark_inset

# Initializing the curve
fig = plt.figure()
main_ax1 = fig.add_subplot(111)
main_ax2 = main_ax1.twinx()

# quantities to plot
Tension = np.linspace(0,0.08,100)
Weight = 0.5 * Tension
Mass = Weight/9.81

# Plotting the curve
main_ax1.plot(Tension, Weight, 'r', label='Fitted line',lw=2)
main_ax2.plot(Tension, Mass)

# Cosmetic on the Figure
main_ax1.set_xlabel("Tension U [$V$]")
main_ax1.set_ylabel("Weight F [$N$]")
main_ax2.set_ylabel("Mass M [$kg$]")
main_ax2.set_ylim(main_ax1.axis()[-2]/9.81, main_ax1.axis()[-1]/9.81)

# Zoom on the first measurement
zoom_ax1 = zoomed_inset_axes(main_ax1, zoom = 7.5, bbox_to_anchor=(0.95,0.5), bbox_transform=main_ax1.transAxes)
mark_inset(main_ax1, zoom_ax1, loc1=2, loc2=4, fc="none", ec="0.5")
zoom_ax1.plot(Tension[:4], Weight[:4], 'r', lw=2)

The unexpected behavior happens here:

# this happens to `main_ax2` istead of `zoom_ax1`
zoom_ax2 = zoom_ax1.axes.twinx()
zoom_ax2.plot(Tension[:4], Mass[:4],alpha=0)


tacaswell commented Nov 27, 2013

Still does not work on recent-ish master.


cimarronm commented Feb 13, 2014

The main problem here is that the zoomed_inset_axes returns an axes located at plot time and the twin functions replicate it without copying the locatable properties so it defaults to the normal axes location. The HostAxes in mpl_toolkits is a better choice and will give the expected behavior as it correctly performs twin operations using a parasite axes.

PR #2805 changes zoom_inset_axes to give that axes class as default and you will get the expected behavior


Alternatively, you can get this by calling zoomed_inset_axes using the axes_class argument with

zoom_ax1 = zoomed_inset_axes(main_ax1, zoom = 7.5, bbox_to_anchor=(0.95,0.5),
                             bbox_transform=main_ax1.transAxes, axes_class=HostAxes)

tacaswell commented Feb 25, 2014

fixed by #2805

@tacaswell tacaswell closed this Feb 25, 2014

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