93 votes

Comment ajouter un deuxième axe des x dans matplotlib

J'ai une question très simple. J'ai besoin d'avoir un deuxième axe x sur mon graphique et je veux que cet axe ait un certain nombre de tics qui correspondent à certaines positions du premier axe.

Essayons avec un exemple. Ici, je trace la masse de matière noire en fonction du facteur d'expansion, défini comme 1/(1+z), qui va de 0 à 1.

semilogy(1/(1+z),mass_acc_massive,'-',label='DM')
xlim(0,1)
ylim(1e8,5e12)

Je voudrais avoir un autre axe x, en haut de mon graphique, montrant le z correspondant pour certaines valeurs du facteur d'expansion. Est-ce possible ? Si oui, comment puis-je avoir l'axe xtics ?

134voto

Hooked Points 16345

D'après les commentaires de la réponse de @Dhara, il semblerait que vous souhaitiez définir une liste de new_tick_locations par une fonction de l'ancien axe des x au nouvel axe des x. Le site tick_function ci-dessous prend un tableau numpy de points, les transforme en une nouvelle valeur et les formate :

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

X = np.linspace(0,1,1000)
Y = np.cos(X*20)

ax1.plot(X,Y)
ax1.set_xlabel(r"Original x-axis: $X$")

new_tick_locations = np.array([.2, .5, .9])

def tick_function(X):
    V = 1/(1+X)
    return ["%.3f" % z for z in V]

ax2.set_xlim(ax1.get_xlim())
ax2.set_xticks(new_tick_locations)
ax2.set_xticklabels(tick_function(new_tick_locations))
ax2.set_xlabel(r"Modified x-axis: $1/(1+X)$")
plt.show()

enter image description here

31voto

Dhara Points 2217

Vous pouvez utiliser twiny pour créer 2 échelles sur l'axe des abscisses. Par exemple :

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny()

a = np.cos(2*np.pi*np.linspace(0, 1, 60.))

ax1.plot(range(60), a)
ax2.plot(range(100), np.ones(100)) # Create a dummy plot
ax2.cla()
plt.show()

Réf : http://matplotlib.sourceforge.net/faq/howto_faq.html#multiple-y-axis-scales

Sortie : enter image description here

17voto

Adobe Points 1592

Si vous voulez que l'axe supérieur soit une fonction des valeurs de l'axe inférieur, vous pouvez procéder comme suit. Veuillez noter que parfois get_xticks() aura un ticks en dehors de la plage visible, ce que vous devez prendre en compte lors de la conversion.

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots()

ax1 = fig.add_subplot(111)

ax1.plot(range(5), range(5))

ax1.grid(True)

ax2 = ax1.twiny()
ax2.set_xticks( ax1.get_xticks() )
ax2.set_xbound(ax1.get_xbound())
ax2.set_xticklabels([x * 2 for x in ax1.get_xticks()])

title = ax1.set_title("Upper x-axis ticks are lower x-axis ticks doubled!")
title.set_y(1.1)
fig.subplots_adjust(top=0.85)

fig.savefig("1.png")

Donne :

enter image description here

14voto

Delenges Points 271

A partir de matplotlib 3.1, vous pouvez utiliser ax.secondary_xaxis

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(1,13, num=301)
y = (np.sin(x)+1.01)*3000

# Define function and its inverse
f = lambda x: 1/(1+x)
g = lambda x: 1/x-1

fig, ax = plt.subplots()
ax.semilogy(x, y, label='DM')

ax2 = ax.secondary_xaxis("top", functions=(f,g))

ax2.set_xlabel("1/(x+1)")
ax.set_xlabel("x")
plt.show()

13voto

carla gama Points 867

Réponse à votre question dans les commentaires de la réponse de Dhara : " Je voudrais sur le deuxième axe des x ces tics : (7,8,99) correspondant à la position des x 10, 30, 40. Cela est-il possible d'une manière ou d'une autre ? " Oui, c'est vrai.

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)

a = np.cos(2*np.pi*np.linspace(0, 1, 60.))
ax1.plot(range(60), a)

ax1.set_xlim(0, 60)
ax1.set_xlabel("x")
ax1.set_ylabel("y")

ax2 = ax1.twiny()
ax2.set_xlabel("x-transformed")
ax2.set_xlim(0, 60)
ax2.set_xticks([10, 30, 40])
ax2.set_xticklabels(['7','8','99'])

plt.show()

Vous aurez : enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X