I would like to have an upper X axis with ticks at identical positions (on the axis) as the original x axis ticks (the tick labels can be different though). It seems easy enough to do, but I am not sure why the code below doesn't work:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
X = np.linspace(11,80,1000)
Y = 2*np.sin(X)*np.exp(-X/20.)
ax1.plot(X,Y)
ax2 = ax1.twiny()
old_ticks = ax1.get_xticks()
ax2.set_xticks(old_ticks)
plt.show()
The output is shown below: clearly, the ticks on the top axis are not in the same location on the axis as the ticks below (namely, on the top axis there are 7 ticks versus only 6 ticks on the bottom).
Why is this so?

EDIT: Setting xlim (as suggested below) works only on initial plot, but not when one zooms in on different regions. I added a callback function to, upon zooming in/out, add the ticks on ax2 in the same location as they are on ax1, but this doesn't seem to work.
Also, the reason I'm using twiny is because eventually the shown tick values for ax2 will depend on the ax1 tick values in a non-linear way. I just want the ticks to be in the same position on the axis.
    import numpy as np
    import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
X = np.linspace(11,80,1000)
Y = 2*np.sin(X)*np.exp(-X/20.)
ax1.plot(X,Y)
ax2 = ax1.twiny()
ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(ax1.get_xticks())
def on_xlim_changed(ax1):
    ax2.set_xlim(ax1.get_xlim())
    ax2.set_xticks(ax1.get_xticks())
ax1.callbacks.connect('xlim_changed',on_xlim_changed)
plt.show()
                try:
ax2.set_xlim(ax1.get_xlim())
also, if you just need ticks to be shown on the top, you do not need a twiny axis, and you may simply do
ax1.xaxis.set_ticks_position('both')
                        The trick here is to disable zooming on the secondary axis with ax2.set_navigate(False). Adjusting the limits in the callback only has an effect if zooming does not affect the limits of the axis itself:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
x = np.linspace(11, 80, 1000)
y = 2 * np.sin(x) * np.exp(-x / 20.)
ax1.plot(x, y)
ax2 = ax1.twiny()
ax2.set_navigate(False)  # Important!
old_ticks = ax1.get_xticks()
ax2.set_xticks(old_ticks)
ax1.grid(linewidth=1, ls='--') # Added to be able to see the (mis-)alignment better.
ax2.set_xlim(ax1.get_xlim())
def on_xlim_changed(ax_):
    ax2.set_xticks(ax_.get_xticks())
    ax2.set_xlim(ax_.get_xlim())
ax1.callbacks.connect('xlim_changed', on_xlim_changed)
plt.show()
set_navigate(False)


If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With