web-dev-qa-db-fra.com

Matplotlib: ValueError: x et y doivent avoir la même première dimension

J'essaie d'ajuster une droite linéaire de meilleur ajustement à mon graphique matplotlib. Je continue à avoir l’erreur que x et y n’ont pas la même première dimension. Mais ils ont tous les deux une longueur de 15. Qu'est-ce que je fais mal?

import matplotlib.pyplot as plt
from scipy import stats
import numpy as np

x = [0.46,0.59,0.68,0.99,0.39,0.31,1.09,0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78]
y = [0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,0.478,0.335,0.365,0.424,0.390,0.585,0.511]
xerr = [0.01]*15
yerr = [0.001]*15

plt.rc('font', family='serif', size=13)
m, b = np.polyfit(x, y, 1)
plt.plot(x,y,'s',color='#0066FF')
plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
plt.xlabel('$\Delta t$ $(s)$',fontsize=20)
plt.ylabel('$\Delta p$ $(hPa)$',fontsize=20)
plt.autoscale(enable=True, axis=u'both', tight=False)
plt.grid(False)
plt.xlim(0.2,1.2)
plt.ylim(0,0.8)
plt.show()
31
Sam

Vous devriez faire x et y numpy des tableaux, pas des listes:

x = np.array([0.46,0.59,0.68,0.99,0.39,0.31,1.09,
              0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78])
y = np.array([0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,
              0.478,0.335,0.365,0.424,0.390,0.585,0.511])

Avec ce changement, il produit l'intrigue attendue. S'ils sont des listes, m * x ne produira pas le résultat attendu, mais une liste vide. Notez que m est anumpy.float64 scalaire, pas un standard Python float.

En fait, je considère ce comportement un peu douteux de Numpy. En Python normal, multiplier une liste avec un entier répète simplement la liste:

In [42]: 2 * [1, 2, 3]
Out[42]: [1, 2, 3, 1, 2, 3]

en multipliant une liste avec un float donne une erreur (comme je le pense bien):

In [43]: 1.5 * [1, 2, 3]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-d710bb467cdd> in <module>()
----> 1 1.5 * [1, 2, 3]
TypeError: can't multiply sequence by non-int of type 'float'

Ce qui est étrange, c’est que multiplier une liste Python avec un scalaire Numpy fonctionne apparemment):

In [45]: np.float64(0.5) * [1, 2, 3]
Out[45]: []

In [46]: np.float64(1.5) * [1, 2, 3]
Out[46]: [1, 2, 3]

In [47]: np.float64(2.5) * [1, 2, 3]
Out[47]: [1, 2, 3, 1, 2, 3]

Il semble donc que le float soit tronqué en un int, après quoi vous obtenez le comportement standard Python de répéter la liste, ce qui est un comportement assez inattendu. Le mieux aurait été de générer une erreur (pour que vous ayez repéré le problème vous-même au lieu de devoir poser votre question sur Stackoverflow) ou simplement montrer la multiplication attendue élément par élément (dans laquelle votre code aurait juste fonctionné). Fait intéressant, addition entre une liste et un Numpy scalaire fonctionne:

In [69]: np.float64(0.123) + [1, 2, 3]
Out[69]: array([ 1.123,  2.123,  3.123])
35
Bas Swinckels

Changer vos listes en numpy tableaux fera l'affaire !!

import matplotlib.pyplot as plt
from scipy import stats
import numpy as np 

x = np.array([0.46,0.59,0.68,0.99,0.39,0.31,1.09,0.77,0.72,0.49,0.55,0.62,0.58,0.88,0.78]) # x is a numpy array now
y = np.array([0.315,0.383,0.452,0.650,0.279,0.215,0.727,0.512,0.478,0.335,0.365,0.424,0.390,0.585,0.511]) # y is a numpy array now
xerr = [0.01]*15
yerr = [0.001]*15

plt.rc('font', family='serif', size=13)
m, b = np.polyfit(x, y, 1)
plt.plot(x,y,'s',color='#0066FF')
plt.plot(x, m*x + b, 'r-') #BREAKS ON THIS LINE
plt.errorbar(x,y,xerr=xerr,yerr=0,linestyle="None",color='black')
plt.xlabel('$\Delta t$ $(s)$',fontsize=20)
plt.ylabel('$\Delta p$ $(hPa)$',fontsize=20)
plt.autoscale(enable=True, axis=u'both', tight=False)
plt.grid(False)
plt.xlim(0.2,1.2)
plt.ylim(0,0.8)
plt.show()

enter image description here

8
ThePredator