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

Plotly添加Trace至子图时触发ValueError问题排查

Plotly子图添加数据触发ValueError的解决方法

问题情况

用Plotly向子图添加数据时持续触发ValueError,单独绘制折线图可正常运行,尝试切换至plotly.graph_objects时遇到模块类错误,已尝试将数据转换为列表和元组,问题仍存在。

错误信息

ValueError: 
    Invalid element(s) received for the 'data' property of 
        Invalid elements include: [Figure({
    'data': [{'hovertemplate': 'year=%{x}<br>value_sum=%{y}<extra></extra>',
              'legendgroup': '',
              'line': {'color': '#636efa', 'dash': 'solid'},
              'marker': {'symbol': 'circle'},
              'mode': 'lines',
              'name': '',
              'orientation': 'v',
              'showlegend': False,
              'type': 'scatter',
              'x': array(['2018', '2018', '2018', '2019', '2019', '2019', '2020', '2020', '2020',
                          '2021', '2021', '2021'], dtype=object),
              'xaxis': 'x',
              'yaxis': 'y'}],
    'layout': {'legend': {'tracegroupgap': 0},
               'margin': {'t': 60},
               'template': '...',
               'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'year'}},
               'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'value_sum'}}}
})]
The 'data' property is a tuple of trace instances
that may be specified as:
  - A list or tuple of trace instances
    (e.g. [Scatter(...), Bar(...)])
  - A single trace instance
    (e.g. Scatter(...), Bar(...), etc.)
  - A list or tuple of dicts of string/value properties where:
    - The 'type' property specifies the trace type
        One of: ['bar', 'barpolar', 'box', 'candlestick',
                 'carpet', 'choropleth', 'choroplethmapbox',
                 'cone', 'contour', 'contourcarpet',
                 'densitymapbox', 'funnel', 'funnelarea',
                 'heatmap', 'heatmapgl', 'histogram',
                 'histogram2d', 'histogram2dcontour', 'icicle',
                 'image', 'indicator', 'isosurface', 'mesh3d',
                 'ohlc', 'parcats', 'parcoords', 'pie',
                 'pointcloud', 'sankey', 'scatter',
                 'scatter3d', 'scattercarpet', 'scattergeo',
                 'scattergl', 'scattermapbox', 'scatterpolar',
                 'scatterpolargl', 'scattersmith',
                 'scatterternary', 'splom', 'streamtube',
                 'sunburst', 'surface', 'table', 'treemap',
                 'violin', 'volume', 'waterfall']

    - All remaining properties are passed to the constructor of
      the specified trace type

    (e.g. [{'type': 'scatter', ...}, {'type': 'bar, ...}])

原代码

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

data='''
    Use-Cases   2018    2019    2020    2021
0   Consumer    50      251     2123    210
1   Education   541     52      32      23
2   Government  689     444     441     456
'''

df = pd.read_csv(StringIO(data), sep='\s+')

# Go from a wide to long dataframe using melt
df = pd.melt(df, id_vars=[ 'Use-Cases'], value_vars=['2018', '2019', '2020', '2021'])
df = df.rename(columns={ 'variable': 'year'})

# get totals for each year so the percent calculation can be done
aggregated_df = df[[ 'value', 'year']].groupby(['year']).agg(['sum']).reset_index()
aggregated_df.columns = ['year', 'value_sum']
df = pd.merge(df, aggregated_df, on=['year'], how='left')

# Caclulate percents and format the column
df['percent'] = (df['value']/df['value_sum']*100).round(1).astype(str) + "%"
df

fig = make_subplots(rows=1, cols=2)
fig.add_trace(px.line(df,df.year,df.value_sum))

问题原因

  1. px.line()返回的是完整的Figure对象,但fig.add_trace()要求传入的是单个/多个Trace对象(比如Scatter、Bar),不是整个Figure,这是触发ValueError的核心原因。
  2. 原代码未导入make_subplots函数,会导致模块类错误。

修正方案

步骤1:导入缺失的模块

从plotly.subplots导入make_subplots。

步骤2:提取Plotly Express生成的Trace

先通过px.line()生成折线图的Figure,再提取其中的Trace对象(figure.data[0]),再添加到子图中。

步骤3:指定子图位置(可选)

添加Trace时通过row和col参数指定它在子图中的位置。

修正后的完整代码

from io import StringIO
import pandas as pd
import plotly.express as px
from plotly.subplots import make_subplots  # 导入缺失的模块

data='''
    Use-Cases   2018    2019    2020    2021
0   Consumer    50      251     2123    210
1   Education   541     52      32      23
2   Government  689     444     441     456
'''

df = pd.read_csv(StringIO(data), sep='\s+')

# 宽表转长表
df = pd.melt(df, id_vars=['Use-Cases'], value_vars=['2018', '2019', '2020', '2021'])
df = df.rename(columns={'variable': 'year'})

# 计算年度总和
aggregated_df = df[['value', 'year']].groupby(['year']).agg(['sum']).reset_index()
aggregated_df.columns = ['year', 'value_sum']
df = pd.merge(df, aggregated_df, on=['year'], how='left')

# 计算百分比
df['percent'] = (df['value']/df['value_sum']*100).round(1).astype(str) + "%"

# 创建子图
fig = make_subplots(rows=1, cols=2)

# 生成折线图并提取trace
line_fig = px.line(df, x='year', y='value_sum')
fig.add_trace(line_fig.data[0], row=1, col=1)  # 将trace添加到子图的第1行第1列

# 可以继续添加其他trace到第2列,比如柱状图
bar_fig = px.bar(df, x='year', y='value', color='Use-Cases')
for trace in bar_fig.data:
    fig.add_trace(trace, row=1, col=2)

# 设置布局
fig.update_layout(height=400, width=800, title_text="子图示例")
fig.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:16:05