24 votes

deux (ou plus) graphiques dans un seul tracé avec des échelles différentes pour les axes des x et des y en python

Je veux 3 graphiques sur un seul objet d'axe, par exemple :

#example x- and y-data
x_values1=[1,2,3,4,5]
y_values1=[1,2,3,4,5]

x_values2=[-1000,-800,-600,-400,-200]
y_values2=[10,20,39,40,50]

x_values3=[150,200,250,300,350]
y_values3=[10,20,30,40,50]

#make axes
fig=plt.figure()
ax=fig.add_subplot(111)

Je veux maintenant ajouter les trois ensembles de données à ax. Mais ils ne doit pas partager d'axe des x ou des y (puisque, en raison des différentes échelles, l'une serait beaucoup plus petite que l'autre). J'ai besoin de quelque chose comme ax.twinx(), ax.twiny(), mais les axes x et y doivent être indépendants.

Je veux faire cela parce que je veux mettre les deux parcelles attachées (et une troisième, qui est similaire à la deuxième) dans une seule parcelle ("les mettre l'une sur l'autre"). Plot1 Plot2

Je placerais alors les étiquettes x/y (et/ou les ticks, les limites) du deuxième graphique à droite/en haut et les limites x/y d'un autre graphique en bas/à gauche. Je n'ai pas besoin des étiquettes x/y du troisième graphique.

Comment faire ?

57voto

ImportanceOfBeingErnest Points 119438

L'idée serait de créer trois intrigues secondaires au même endroit. Afin de s'assurer qu'elles seront reconnues comme des parcelles différentes, leurs propriétés doivent être différentes - et la façon la plus simple d'y parvenir est simplement de fournir une étiquette différente, ax=fig.add_subplot(111, label="1") .

Le reste consiste simplement à ajuster tous les paramètres des axes, de manière à ce que le tracé obtenu soit attrayant. Le réglage de tous les paramètres demande un peu de travail, mais ce qui suit devrait faire l'affaire.

enter image description here

import matplotlib.pyplot as plt

x_values1=[1,2,3,4,5]
y_values1=[1,2,2,4,1]

x_values2=[-1000,-800,-600,-400,-200]
y_values2=[10,20,39,40,50]

x_values3=[150,200,250,300,350]
y_values3=[10,20,30,40,50]

fig=plt.figure()
ax=fig.add_subplot(111, label="1")
ax2=fig.add_subplot(111, label="2", frame_on=False)
ax3=fig.add_subplot(111, label="3", frame_on=False)

ax.plot(x_values1, y_values1, color="C0")
ax.set_xlabel("x label 1", color="C0")
ax.set_ylabel("y label 1", color="C0")
ax.tick_params(axis='x', colors="C0")
ax.tick_params(axis='y', colors="C0")

ax2.scatter(x_values2, y_values2, color="C1")
ax2.xaxis.tick_top()
ax2.yaxis.tick_right()
ax2.set_xlabel('x label 2', color="C1") 
ax2.set_ylabel('y label 2', color="C1")       
ax2.xaxis.set_label_position('top') 
ax2.yaxis.set_label_position('right') 
ax2.tick_params(axis='x', colors="C1")
ax2.tick_params(axis='y', colors="C1")

ax3.plot(x_values3, y_values3, color="C3")
ax3.set_xticks([])
ax3.set_yticks([])

plt.show()

2voto

Tristan Points 1306

Vous pouvez également normaliser les données de manière à ce qu'elles partagent les mêmes limites, puis tracer "manuellement" les limites de la deuxième échelle souhaitée. Cette fonction normalise les données aux limites de la première série de points :

def standardize(data):
    for a in range(2):
        span = max(data[0][a]) - min(data[0][a])
        min_ = min(data[0][a])
        for idx in range(len(data)):
            standardize = (max(data[idx][a]) - min(data[idx][a]))/span
            data[idx][a] = [i/standardize + min_ - min([i/standardize 
                            for i in data[idx][a]]) for i in data[idx][a]]
    return data

Il est ensuite facile de tracer les données :

import matplotlib.pyplot as plt
data = [[[1,2,3,4,5],[1,2,2,4,1]], [[-1000,-800,-600,-400,-200], [10,20,39,40,50]], [[150,200,250,300,350], [10,20,30,40,50]]]
limits = [(min(data[1][a]), max(data[1][a])) for a in range(2)]

norm_data = standardize(data)

fig, ax = plt.subplots()

for x, y in norm_data:
    ax.plot(x, y)

ax2, ax3 = ax.twinx(), ax.twiny()
ax2.set_ylim(limits[1])
ax3.set_xlim(limits[0])

plt.show()

Comme tous les points de données ont les limites de la première série de points, nous pouvons simplement les représenter sur le même axe. Ensuite, en utilisant les limites des seconds axes x et y souhaités, nous pouvons définir les limites de ces deux axes.

Rsulting plot

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