3

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,

Community
  • 1
  • 1
Florian M.
  • 301
  • 3
  • 15

1 Answers1

1

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...)

pathoren
  • 1,634
  • 2
  • 14
  • 22
  • I corrected the typos. No it doesn't work (see the edits in the question). I think I got a misunderstanding of what does exactly ax2.set_ticks(), and the matplotlip help is shallow. – Florian M. Aug 17 '16 at 18:37
  • 1
    Ok I got it. I misread your text, which doesn't fit with the code you wrote. `ax2.set_xlim(ax1.get_xlim())` must come last – Florian M. Aug 17 '16 at 18:42