web-dev-qa-db-fra.com

deux graphes (ou plus) dans un même tracé avec différentes échelles d'axe x et y en python

Je veux 3 graphes sur un objet d'axes, 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)

maintenant, je veux ajouter les trois ensembles de données à ax. Mais ils ne doivent pas partager les axes des x ou des y (depuis, à cause 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 semblable à la seconde) dans une parcelle ("les mettre l'une sur l'autre") . Plot1Plot2

Je mettrais ensuite les étiquettes x/y (et/ou les graduations, les limites) du deuxième tracé à droite/en haut et les limites x/y d'un autre tracé en bas/à gauche. Je n'ai pas besoin d'étiquettes x/y de l'intrigue 3..

Comment puis-je faire cela?

8
Anton Rodenhauser

L'idée serait de créer trois sous-parcelles à la même position. Pour être sûr qu'ils seront reconnus en tant que parcelles différentes, leurs propriétés doivent différer - et le moyen le 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 sorte que le tracé résultant semble attrayant. Il est un peu de travail pour définir tous les paramètres, mais ce qui suit devrait faire ce que vous avez besoin.

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

Vous pouvez également normaliser les données pour 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 du premier ensemble 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

Ensuite, tracer les données est facile:

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 du premier ensemble de points, nous pouvons simplement les tracer sur le même axe. Ensuite, en utilisant les limites du second axe x et y souhaité, vous pouvez définir les limites pour ces deux axes.

 Rsulting plot

1
Tristan