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

使用Plotly Express绘制误差条报错:参数长度不匹配

问题:Plotly Express绘制误差条时出现长度不匹配错误

错误信息:

ValueError: All arguments should have the same length. The length of argument `error_y` is 6, whereas the length of previously-processed arguments ['x', 'y'] is 3

相关代码:

import plotly.express as px
import pandas as pd
import numpy as np
from io import StringIO

def save_fig(fig,pngname):
    fig.write_image(pngname,format="png", width=800, height=300, scale=1)
    print("[[%s]]"%pngname)
    #plt.show()
    return

def date_linspace(start, end, steps):
    delta = (end - start) / (steps-1)
    increments = range(0, steps) * np.array([delta]*steps)
    return start + increments

def plot_timedelta(x,y,colors,pngname):
    fig = px.scatter(
        x=x,
        y=y,
        color=colors,
        error_y=dict(
            type='data',
            symmetric=False,
            arrayminus=y,
            array=[0] * len(y),
            thickness=1,
            width=0,
        ),         
    )
    
    tickvals = date_linspace(x.min(),x.max(),15)
    print(x.min(),x.max())
    layout =dict(
        title="demo",
        xaxis_title="X",
        yaxis_title="Y",
        title_x=0.5,   
        margin=dict(l=10,t=20,r=0,b=40),
        height=300,
        xaxis=dict(
            tickangle=-25,
            tickvals = tickvals,
            ticktext=[d.strftime('%m-%d %H:%M:%S') for d in tickvals]
        ),
        yaxis=dict(
            showgrid=True,
            zeroline=False,
            showline=False,
            showticklabels=True
        )
    )

    fig.update_traces(
        marker_size=14,
    )    
    fig.update_layout(layout)
    
    save_fig(fig,pngname)
    return

def get_delta(df):
    df['delta'] = df['ts'].diff().dt.total_seconds()
    df['prev'] = df['ts'].shift(1)
    print("delta min:",df['delta'].min())
    print("delta max:",df['delta'].max())
    #df = df[df['delta'] >= 40]    
    return df

data = """ts,source
2022-12-12 15:46:20.350,izat
2022-12-12 15:46:36.372,skyhook
2022-12-12 15:46:37.181,skyhook
"""

csvtext = StringIO(data)

df = pd.read_csv(csvtext, sep=",")
df['ts'] = pd.to_datetime(df['ts'])
df = get_delta(df)
df['delta'] = df['delta'].fillna(0)
plot_timedelta(df['ts'],df['delta'],df['source'],"demo.png")
解决方案

错误原因

使用px.scatter时,color=colors会按colors的不同值生成多条独立轨迹(这里有2个分组:izat、skyhook)。直接在px.scatter的error_y中传入长度为3的数组,Plotly会将该数组重复应用到每条轨迹上,导致总长度变为3×2=6,与单条轨迹的长度不匹配,触发报错。

修改方法

方法1:通过update_traces设置误差条

先创建基础散点图,再用update_traces为所有轨迹统一设置误差条:

def plot_timedelta(x,y,colors,pngname):
    # 先创建无误差条的散点图
    fig = px.scatter(
        x=x,
        y=y,
        color=colors,
    )
    
    # 为每条轨迹添加误差条配置
    fig.update_traces(
        marker_size=14,
        error_y=dict(
            type='data',
            symmetric=False,
            arrayminus=y,
            array=[0] * len(y),
            thickness=1,
            width=0,
        )
    )
    
    tickvals = date_linspace(x.min(),x.max(),15)
    print(x.min(),x.max())
    layout =dict(
        title="demo",
        xaxis_title="X",
        yaxis_title="Y",
        title_x=0.5,   
        margin=dict(l=10,t=20,r=0,b=40),
        height=300,
        xaxis=dict(
            tickangle=-25,
            tickvals = tickvals,
            ticktext=[d.strftime('%m-%d %H:%M:%S') for d in tickvals]
        ),
        yaxis=dict(
            showgrid=True,
            zeroline=False,
            showline=False,
            showticklabels=True
        )
    )
    
    fig.update_layout(layout)
    
    save_fig(fig,pngname)
    return

方法2:传入完整DataFrame让Plotly自动匹配

将所有数据(包括误差相关)存入DataFrame,直接传入px.scatter,Plotly会自动按分组匹配对应数据:

def plot_timedelta(df,pngname):
    fig = px.scatter(
        df,
        x='ts',
        y='delta',
        color='source',
        error_y=dict(
            type='data',
            symmetric=False,
            arrayminus='delta',  # 直接引用DataFrame列名
            array=[0]*len(df),
            thickness=1,
            width=0,
        )
    )
    
    tickvals = date_linspace(df['ts'].min(),df['ts'].max(),15)
    print(df['ts'].min(),df['ts'].max())
    layout =dict(
        title="demo",
        xaxis_title="X",
        yaxis_title="Y",
        title_x=0.5,   
        margin=dict(l=10,t=20,r=0,b=40),
        height=300,
        xaxis=dict(
            tickangle=-25,
            tickvals = tickvals,
            ticktext=[d.strftime('%m-%d %H:%M:%S') for d in tickvals]
        ),
        yaxis=dict(
            showgrid=True,
            zeroline=False,
            showline=False,
            showticklabels=True
        )
    )

    fig.update_traces(marker_size=14)    
    fig.update_layout(layout)
    
    save_fig(fig,pngname)
    return

# 调用时直接传入df
plot_timedelta(df,"demo.png")

说明

当使用color分组时,Plotly会为每个分组创建独立轨迹。直接在px.scatter中设置error_y会导致误差数组被重复应用,引发长度冲突。通过上述两种方式,让误差数据与每条轨迹的实际数据长度匹配,即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:10:29