fmollica fmollica - 3 months ago 21
Python Question

Second matplotlib x-axis related to the first one : wrong tick position

I would like to add a second x-axis to a matplotlib plot, not to add a second plot, but to add labels linked to the first axis. The answers in this question somehow fail to adress a problem in the bounds of the second axis :

The following code plot the log10 of the first x-axis as a second axis :

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(3,figsize = [5,4])
ax1 = fig.add_subplot(111)
ax1.set_xlabel('first axis')
ax1.set_xlim([0, 120])
ax1.grid(True)

ax2 = ax1.twiny()
ax2.set_xlim(ax1.get_xlim())
# or alternatively :
# ax2.set_xbound(ax1.get_xbound())
second_ticks = np.array([1.,10.,100.])
ax2.set_xticks(second_ticks)
ax2.set_xticklabels(np.log10(second_ticks))
ax2.set_xlabel('second axis')

plt.show()


enter image description here

It works !
Now let's change
ax1.set_xlim([0, 120])
by
ax1.set_xlim([20, 120])


enter image description here

Now it fails. I tried with
ax2.set_xbound(ax1.get_xbound())
with no differences. Somehow
ax2.set_xticks
fails to place the ticks according to the right x limits.

EDIT :

I tried to place
ax1.set_xlim([20, 120])
anywhere after
ax2.set_xlim(ax1.get_xlim())
it gives again the wrong things :

enter image description here

Actually i don't get the meaning of
ax2.set_xticks()
, It sets position where ticklabels will be displayed no ?

EDIT :

Ok, we got it : the x_lim definition
ax2.set_xlim(ax1.get_xlim())
must come after the tick and ticklabel definition.


import numpy as np
import matplotlib.pyplot as plt

plt.close('all')

fig = plt.figure(1,figsize = [5,4])
ax1 = fig.add_subplot(111)
ax1.set_xlabel('first axis')
ax1.grid(True)
ax1.set_xlim([10, 120])

ax2 = ax1.twiny()

second_ticks = np.array([1.,10.,100.])
ax2.set_xticks(second_ticks)
ax2.set_xticklabels(np.log10(second_ticks))
ax2.set_xlabel('second axis')
ax2.set_xlim(ax1.get_xlim())

fig.tight_layout()

plt.show()


enter image description here

Thanks !

Regards,

Answer

I believe your are getting unexpected results because you are forcing the x-ticks and the x-tick-labels on the second axis to be something predefined. No matter what you put as x-ticks on the second axis they will always be labeled by: ax2.set_xticklabels(np.log10(second_ticks)). Instead, update the x-tick-labels on the second axis after you have updated them on the first axis

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(3,figsize = [5,4])
ax1 = fig.add_subplot(111)
ax1.set_xlabel('first axis')
x = np.linspace(0,100,num=200)
ax1.set_xlim([0, 120])
ax1.grid(True)

ax2 = ax1.twiny()
ax2.set_xlim(ax1.get_xlim())
# or alternatively :
# ax2.set_xbound(ax1.get_xbound())
# second_ticks = np.array([1.,10.,100.])
# ax2.set_xticks(second_ticks)
ax2.set_xlabel('second axis')

# Set the xlim on axis 1, then update the x-tick-labels on axis 2
ax1.set_xlim([20, 100])
ax2.set_xticklabels(np.log10(ax1.get_xticks()))
plt.show()

Does this solve your problem? (Ps. there are several typos in your code...it is not runnable...)

Comments