Matplotlib: ValueError: x en y moeten dezelfde eerste dimensie hebben

Ik probeer een lineaire lijn te passen die het beste past in mijn matplotlib-grafiek. Ik krijg steeds de fout dat x en y niet dezelfde eerste dimensie hebben. Maar ze hebben allebei een lengte van 15. Wat doe ik verkeerd?

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

Antwoord 1, autoriteit 100%

U moet xen ynumpy arrays maken, geen lijsten:

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

Met deze wijziging wordt de verwachte plot geproduceerd. Als het lijsten zijn, zal m * xniet het verwachte resultaat opleveren, maar een lege lijst. Merk op dat meen numpy.float64scalaire waarde is, geen standaard Python float.

Ik vind dit eigenlijk een beetje dubieus gedrag van Numpy. In normale Python herhaalt het vermenigvuldigen van een lijst met een geheel getal de lijst:

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

terwijl het vermenigvuldigen van een lijst met een float een fout geeft (zoals ik denk dat het zou moeten):

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'

Het rare is dat het vermenigvuldigen van een Python-lijst met een Numpy-scalar blijkbaar werkt:

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]

Het lijkt er dus op dat de float wordt afgekapt tot een int, waarna je het standaard Python-gedrag krijgt van het herhalen van de lijst, wat nogal onverwacht gedrag is. Het beste zou zijn geweest om een fout op te werpen (zodat je het probleem zelf zou hebben opgemerkt in plaats van je vraag op Stackoverflow te moeten stellen) of om gewoon de verwachte elementgewijze vermenigvuldiging te tonen (waarin je code net zou hebben gewerkt) . Interessant is dat optellen tussen een lijst en een Numpy-scalar wel werkt:

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

Antwoord 2, autoriteit 20%

Uw lijsten wijzigen naar numpyARRAYS ZULLEN DE TOOP DOEN !!

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

Other episodes