2014-11-01 219 views
23

我试图拟合最适合我的matplotlib图的线性线。我不断收到x和y不具有相同第一维的错误。但他们都有15的长度。我做错了什么?Matplotlib:ValueError:x和y必须具有相同的第一维

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

你是怎么最终解决您的问题,只是转换为numpy的阵列? – 2017-09-28 19:33:13

回答

29

你应该让xy numpy的阵列,而不是名单:

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

随着这一变化,它产生的预期情节。如果他们是名单,m * x不会产生你期望的结果,但是是一个空的名单。请注意,m是标量,而不是标准Python float

我实际上认为这有点可疑的Numpy行为。在普通的Python,乘以一个整数的列表只是重复列表:

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

同时用浮动乘以一个列表给出了一个错误(因为我认为它应该):

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' 

怪异的事情是一个numpy的标量乘以一个Python列表显然作品:

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] 

如此看来,浮子被截断为int,之后你会得到重复的次标准的Python行为e列表,这是非常意想不到的行为。最好的事情是提出一个错误(以便你自己发现了问题,而不必在Stackoverflow上提出你的问题),或者只是显示预期的元素方式的乘法(你的代码刚刚工作) 。有趣的是,列表和numpy的标量之间除了做工作:

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

等待我不明白,是什么问题?只需转换为'np.array'修复了一些问题? – 2017-09-28 19:31:50

+0

@CharlieParker:是的,它的工作原理。这里没什么奇怪的,让我解释一下。当OP做'm,b = np.polyfit(x,y,1)'时,这里你得到'm'为float64的值,例如'm = 0.642'。现在,当你试图将一个浮点数“m”与一个列表“x”相乘时,你最终会得到一个空列表'[]'。这是因为要将列表中的每个元素与一个值相乘,您需要将列表转换为'numpy数组'或使用内置的'map'函数。看到[这个答案](https://stackoverflow.com/questions/8194959/how-to-multiply-individual-elements-of-a-list-with-a-number)了解更多信息。 – ThePredator 2017-09-29 07:02:00

5

更改您的列表,以numpy阵列将做的工作!

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

这是为什么这样工作?我觉得很奇怪。 – 2017-09-28 19:34:24

+0

@CharlieParker:是的,它的工作原理。这里没什么奇怪的,让我解释一下。当OP做'm,b = np.polyfit(x,y,1)'时,这里你得到'm'为float64的值,例如'm = 0.642'。现在,当你试图将一个浮点数“m”与一个列表“x”相乘时,你最终会得到一个空列表'[]'。这是因为要将列表中的每个元素与一个值相乘,您需要将列表转换为'numpy数组'或使用内置的'map'函数。看到[这个答案](https://stackoverflow.com/questions/8194959/how-to-multiply-individual-elements-of-a-list-with-a-number)了解更多信息。 – ThePredator 2017-09-29 07:00:17

相关问题