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

Plotly调用add_trace添加拟合线时触发numpy.float64类型无效报错

问题场景

调用plotly的add_trace方法添加拟合曲线时报类型错误,场景为:

  • 存在2个自变量x1、x2,1个因变量y
  • 已通过scipy.optimize.curve_fit完成二元函数拟合,需要在散点图上追加拟合轨迹线
  • 测试用数据为随机生成,拟合结果无实际业务意义

附复现代码与报错:

import pandas as pd
import numpy as np
import plotly.graph_objects as go  
from scipy.optimize import curve_fit

np.random.seed(0)
x1 = np.random.randint(0, 100, 100)
x2 = np.random.randint(0, 100, 100)
y = np.random.randint(0, 100, 100)

def func(x, a, b, c, d, e, f, g):
    return (a * x[0]**3 + b * x[0]**2 + c * x[0]) + (d * x[1]**3 + e * x[1]**2 + f * x[1]) + g

def inv(x1, x2, y):
    (a, b, c, d, e, f, g), _ = curve_fit(func, np.stack([x1, x2]), y)

    # create graph
    x3 = [sum(i) for i in zip(x1, x2 )]  
    x = np.linspace(min(x3), max(y), 1000)

    fig = go.Figure(go.Scatter(x=x3, y=y, name='data'))
    fig.add_trace(go.Scatter(x=x, y=func(x, a, b, c, d, e, f, g), name='fit'))
    fig.show()
    
    return  (a, b, c, d, e, f, g)

inv(x1, x2, y)

报错信息:

ValueError: 
Invalid value of type 'numpy.float64' received for the 'y' property of scatter
    Received value: 49.464592654826

The 'y' property is an array that may be specified as a tuple,
list, numpy array, or pandas Series
报错原因

问题出在两处逻辑错误:

  1. 直接触发报错的原因:定义的拟合函数func要求输入的x是形状为(2, n)的二维数组(第一行存x1序列、第二行存x2序列),但绘图时生成的x是一维数组,直接传入func后,x[0]取到的是数组第一个元素(单个numpy.float64数值),整个函数计算后返回的是单个浮点数,不符合plotly Scatter的y参数需要传入序列的要求。
  2. 额外的逻辑偏差:
    • 生成拟合x轴范围时用了max(y)作为上限,但散点x轴是x1+x2的和x3,x轴范围应该对齐x3的极值,和y的最大值无关。
    • 二元函数拟合结果本质是三维曲面,要在二维平面图上绘制拟合线,必须先明确一维x轴上每个点对应的x1、x2取值规则,不能直接把一维x传入二元拟合函数。
修复方案
  1. 调整拟合x轴的生成范围,对齐原始散点x轴(x3)的最小、最大值
  2. 定义一维拟合x对应的x1、x2取值规则(示例中取x1=x2=x/2,可根据实际展示需求调整,比如固定其中一个变量为样本均值,另一个随x变化),将两个拟合自变量拼成(2, n)形状的二维数组后再传入func计算拟合y值。

修正后可运行代码:

import numpy as np
import plotly.graph_objects as go  
from scipy.optimize import curve_fit

np.random.seed(0)
x1 = np.random.randint(0, 100, 100)
x2 = np.random.randint(0, 100, 100)
y = np.random.randint(0, 100, 100)

def func(x, a, b, c, d, e, f, g):
    return (a * x[0]**3 + b * x[0]**2 + c * x[0]) + (d * x[1]**3 + e * x[1]**2 + f * x[1]) + g

def inv(x1, x2, y):
    (a, b, c, d, e, f, g), _ = curve_fit(func, np.stack([x1, x2]), y)

    # 原始散点x轴为x1+x2的和
    x3 = x1 + x2
    # 生成拟合x轴,范围对齐x3
    x_fit = np.linspace(x3.min(), x3.max(), 1000)
    # 定义x_fit对应的x1、x2取值,示例为x1=x2=x_fit/2,可按需调整
    x1_fit = x_fit / 2
    x2_fit = x_fit / 2
    # 拼成func要求的(2, n)形状输入
    x_fit_2d = np.stack([x1_fit, x2_fit])
    # 计算拟合y值
    y_fit = func(x_fit_2d, a, b, c, d, e, f, g)

    fig = go.Figure()
    fig.add_trace(go.Scatter(x=x3, y=y, mode='markers', name='raw data'))
    fig.add_trace(go.Scatter(x=x_fit, y=y_fit, mode='lines', name='fit curve'))
    fig.show()
    
    return  (a, b, c, d, e, f, g)

inv(x1, x2, y)

注:如果需要完整展示二元拟合的曲面效果,应改用3D散点+3D曲面图绘制,不要在二维图中强行降维展示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:54:20