web-dev-qa-db-fra.com

Comment ajouter un deuxième axe x dans matplotlib

J'ai une question très simple. J'ai besoin d'un deuxième axe x sur mon graphique et je souhaite que cet axe comporte un certain nombre de tics correspondant à une certaine position du premier axe.

Essayons avec un exemple. Ici, je trace la masse de matière noire en fonction du facteur de dilatation, défini par 1/(1 + z), compris entre 0 et 1.

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

Je voudrais avoir un autre axe des 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 xtics ax

72
Brian

Je me fie aux commentaires de la réponse de @ Dhara, on dirait que vous voulez définir une liste de new_tick_locations par une fonction de l’ancien axe x au nouvel axe x. Le tick_function ci-dessous prend un tableau numpy de points, les mappe sur 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

98
Hooked

Vous pouvez utiliser Twiny pour créer des échelles à 2 axes x. 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

24
Dhara

Si vous souhaitez que votre axe supérieur soit fonction des valeurs de graduation de l'axe inférieur:

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()
ax1Xs = ax1.get_xticks()

ax2Xs = []
for X in ax1Xs:
    ax2Xs.append(X * 2)

ax2.set_xticks(ax1Xs)
ax2.set_xbound(ax1.get_xbound())
ax2.set_xticklabels(ax2Xs)

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

12
Adobe

Répondant à votre question, Dhara répond: "J'aimerais sur le deuxième axe des abscisses ces tics: (7,8,99) correspondant à la position de l'axe des abscisses 10, 30, 40. Est-ce possible manière? "Oui, ça l'est.

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

Tu auras: enter image description here

9
carla

Je suis obligé de poster cela comme une réponse au lieu d'un commentaire en raison de la faible réputation. J'ai eu un problème similaire à Matteo. La différence étant que je n'avais aucune carte de mon premier axe des x à mon deuxième axe des x, seulement les valeurs x elles-mêmes. Donc, je voulais définir les données sur mon deuxième axe x directement, pas les ticks, cependant, il n'y a pas de axes.set_xdata. J'ai pu utiliser la réponse de Dhara pour le faire avec une modification:

ax2.lines = []

à la place d'utiliser:

ax2.cla()

Lors de son utilisation, j'ai également effacé mon complot de ax1.

1
user2561747