You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python绘图报错:ValueError: err需为标量/1D/(2,n)类数组求助

解决你的Matplotlib ValueError与拟合问题

刚看了你的代码和报错,这几个问题其实都是新手容易踩的小坑,我帮你一步步拆解修正:

核心报错原因:plt.errorbar参数顺序完全搞反

你当前写的:

plt.errorbar(m, sigma_m, V, sigma_V, marker='.', fmt='.')

完全不符合plt.errorbar的参数逻辑!它的标准调用顺序是:
plt.errorbar(x, y, yerr=None, xerr=None, ...)
你的图表是质量-体积关系,x轴对应体积(V),y轴对应质量(m),所以正确写法应该是把x设为V、y设为m,然后yerr传质量的误差sigma_m,xerr传体积的误差sigma_V。你现在把误差值直接放在了x、y的位置,导致程序把V当成了yerr参数,而V是数组格式不符合要求,这就是触发ValueError: err must be a scalar or a 1D or (2, n) array-like的直接原因。

第二个关键问题:curve_fit参数顺序颠倒

curve_fit的调用逻辑是:curve_fit(拟合函数, x数据, y数据, ...),你现在写的:

popt, pcov=curve_fit(m, V, line)

不仅把拟合函数放在了最后,还搞反了x、y数据的顺序,正确写法应该是curve_fit(line, V, m)——毕竟你是要用体积V去拟合质量m。

隐性小问题:数据加载导致的二维数组

你加载数据时用了np.array([np.loadtxt('xxx.txt')]),比如:

m=np.array([np.loadtxt('masse.txt')])

这会把原本一维的数值数组变成二维数组(形状为(1, n)),而Matplotlib和curve_fit都需要一维数组处理,直接改成m = np.loadtxt('masse.txt')即可,其他加载数据的行同理。

误差计算的疏漏

你的sigma_Vpe计算少了开平方步骤,误差传递公式里平方和之后需要开根号,所以应该改成:

sigma_Vpe=np.sqrt((lpe*a)**2 *(0.01)**2 +(lpe*hpe)**2 *(0.01)**2 +(hpe*a)**2 *(0.01)**2)

修正后的完整代码

import numpy as np
from matplotlib import pyplot as plt
from scipy.optimize import curve_fit

# 修正:直接加载为一维数组,去掉外层冗余的np.array([...])
m = np.loadtxt('masse.txt')
sigma_m = np.loadtxt('errore_masse.txt')
lati = np.loadtxt('lati.txt')
sigma_lati = np.loadtxt('errore_lati.txt')
h = np.loadtxt('altezze.txt')
sigma_h = np.loadtxt('errore_altezza.txt')

dc = np.array([6.45, 8.56, 10.45, 10.46])
hc = np.array([16.25, 40.80, 75., 17.67])
lpe = np.array([8.56])
a = np.array([7.41])
hpe = np.array([37.3])
lb = np.array([10.46])

rc = dc/2
Vc = 2*np.pi*a**2 *hc
sigma_rc = sigma_lati/2
sigma_Vc = Vc*2*(0.01/dc)

# 修正:误差计算添加开平方步骤
Vpe = 6*lpe*a*hpe
sigma_Vpe = np.sqrt((lpe*a)**2 *(0.01)**2 +(lpe*hpe)**2 *(0.01)**2 +(hpe*a)**2 *(0.01)**2)

Vp = lb**2
sigma_Vp = 2*Vp*(0.01/lb)

# 修正:一维数组加载体积数据
V = np.loadtxt('volumi.txt')
sigma_V = np.loadtxt('errore_volumi.txt')

def line(x, a, q):
    '''funzione retta '''
    return a*x+q

plt.figure('Grafico massa-volume oggetti di ottone')
# 修正:errorbar参数顺序,x=体积V,y=质量m,对应误差分别传入
plt.errorbar(V, m, xerr=sigma_V, yerr=sigma_m, marker='.', fmt='.')

# 修正:curve_fit参数顺序,拟合函数在前,x=V、y=m
popt, pcov = curve_fit(line, V, m)
a_fit, q_fit = popt
sigma_a_fit, sigma_q_fit = np.sqrt(pcov.diagonal())
print(a_fit, q_fit, sigma_a_fit, sigma_q_fit)

# 优化:用数据的实际范围生成拟合线的x轴,更贴合图表
x = np.linspace(V.min(), V.max(), 100)  # 100个点让拟合线更平滑
plt.plot(x, line(x, a_fit, q_fit))

plt.xlabel('Volume [mm$^3$]')
plt.ylabel('Massa [g]')
plt.grid(ls='dashed', which='both')
plt.show()

额外小建议

  • 以后调用陌生函数前,可以快速查一下官方文档的参数顺序,plt.errorbar和curve_fit的参数顺序很容易搞混;
  • 加载数据后可以用print(m.shape)检查数组维度,避免二维数组带来的隐性问题;
  • 如果想让拟合结果更准确,可以在curve_fit里加上误差权重参数:
    popt, pcov = curve_fit(line, V, m, sigma=sigma_m, absolute_sigma=True)
    

内容的提问来源于stack exchange,提问作者lore_caram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:09:10