2014-11-01 5 views
23

Sto provando ad adattare una linea lineare di miglior adattamento al mio grafico matplotlib. Continuo a ricevere l'errore che xey non hanno la stessa prima dimensione. Ma entrambi hanno una lunghezza di 15. Cosa sto sbagliando?Matlotlib: ValueError: xey deve avere la stessa prima dimensione

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

così come hai fatto a finire risolvere il tuo problema, solo la conversione in numpy array? –

risposta

29

Si dovrebbe fare x e y array NumPy, non elenca:

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

Con questa modifica, che produce la trama si aspettano. Se sono elenchi, m * x non produrrà il risultato previsto, ma un elenco vuoto. Si noti che m è uno scalare numpy.float64, non un Python standard float.

In realtà considero questo comportamento un po 'dubbioso di Numpy. Nel normale Python, moltiplicando una lista con un numero intero solo ripete la lista:

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

mentre moltiplicando una lista con un galleggiante dà un errore (come penso che dovrebbe):

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' 

La cosa strana è che moltiplicando una lista Python con uno scalare Numpy lavora a quanto pare:

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] 

Così sembra che il galleggiante viene troncato a un int, dopo il quale si ottiene il comportamento standard di Python di ripetere ° e lista, che è un comportamento abbastanza inaspettato. La cosa migliore sarebbe stata di generare un errore (in modo che tu avessi individuato il problema da solo invece di dover fare la tua domanda su Stackoverflow) o semplicemente mostrare la moltiplicazione prevista in base agli elementi (in cui il tuo codice avrebbe funzionato) . È interessante notare, inoltre tra una lista e uno scalare Numpy funziona:

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

attendi Non capisco, qual era il problema? La semplice conversione in 'np.array' risolve le cose? –

+0

@CharlieParker: Sì, funziona. Niente di strano qui, lasciami spiegare. Quando l'OP ha fatto 'm, b = np.polyfit (x, y, 1)', qui si ottiene 'm' come valore float64, ad esempio' m = 0.642' nel caso precedente. Ora, quando si tenta di moltiplicare un 'm' float con una lista' x', si finisce per ottenere una lista vuota '[]'. È perché per moltiplicare ogni elemento di una lista con un valore, è necessario convertire la lista in un 'array numpy' o utilizzare la funzione incorporata' map'. Vedi [questa risposta] (https://stackoverflow.com/questions/8194959/how-to-multiply-individual-elements-of-a-list-with-a-umber) per maggiori informazioni. – ThePredator

5

Cambiare le vostre liste di numpy array farà il lavoro !!

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

+0

perché funziona? Lo trovo davvero strano. –

+0

@CharlieParker: Sì, funziona. Niente di strano qui, lasciami spiegare. Quando l'OP ha fatto 'm, b = np.polyfit (x, y, 1)', qui si ottiene 'm' come valore float64, ad esempio' m = 0.642' nel caso precedente. Ora, quando si tenta di moltiplicare un 'm' float con una lista' x', si finisce per ottenere una lista vuota '[]'. È perché per moltiplicare ogni elemento di una lista con un valore, è necessario convertire la lista in un 'array numpy' o utilizzare la funzione incorporata' map'. Vedi [questa risposta] (https://stackoverflow.com/questions/8194959/how-to-multiply-individual-elements-of-a-list-with-a-umber) per maggiori informazioni. – ThePredator

Problemi correlati