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

使用to_plotly_json保存Dash组件与Plotly饼图为JSON时遇模板错误

问题描述

开发Dash应用时,使用Plotly Express绘制图表,尝试通过to_plotly_json()将Dash组件和图表保存为JSON文件,但处理饼图时出现以下错误:

Error-1 The first argument to the plotly.graph_objs.layout.Template constructor must be a dict or an instance of :class:plotly.graph_objs.layout.Template
Error-1 The first argument to the plotly.graph_objs.layout.Template constructor must be a dict or

最小可复现示例(MWE):

import json

import dash_bootstrap_components as dbc
from dash import dcc

import plotly.express as px

import pandas as pd


def generate_pie_charts(df, template) -> list[dict[str, Any]]:
    pie_charts = list()

    for field in df.columns.tolist():
        
        value_count_df = df[field].value_counts().reset_index()        

        cols = value_count_df.columns.tolist()

        name: str = cols[0]
        value: str = cols[1]

        try:
            figure = px.pie(
                data_frame=value_count_df,
                values=value,
                names=name,
                title=f"Pie chart of {field}",
                template=template,
            ).to_plotly_json()

            pie_chart = dcc.Graph(figure=figure).to_plotly_json()
            
            pie_charts.append(pie_chart)
        except Exception as e:
            print(f"Error-1 {e}")
    
    return pie_charts


def perform_exploratory_data_analysis():
    rows = list()

    template = "darkly"

    info = {
        "A": ["a", "a", "b", "b", "c", "a", "a", "b", "b", "c", "a", "a", "b", "b", "c"],
        "B": ["c", "c", "c", "c", "c", "a", "a", "b", "b", "c", "a", "a", "b", "b", "c"],
    }

    df = pd.DataFrame(info)

    try:
        row = dbc.Badge(
            "For Pie Charts", color="info", className="ms-1"
        ).to_plotly_json()

        rows.append(row)

        row = generate_pie_charts(df, template)  

        rows.append(row)

        data = {"contents": rows}

        status = False

        msg = "Error creating EDA graphs."

        file = "eda.json"

        with open(file, "w") as json_file:
            json.dump(data, json_file)
            msg = "EDA graphs created."
            status = True

    except Exception as e:
        print(f"Error-2 {e}")

    result = (status, msg)

    return result


perform_exploratory_data_analysis()
问题原因

错误出在**先将Plotly figure转成JSON格式,再传给dcc.Graph**的步骤上:

  • 调用px.pie(...).to_plotly_json()后,figure字典中的template字段会被序列化为字符串(比如"darkly")。
  • 当你把这个JSON化的figure传给dcc.Graph(figure=figure)时,Dash会尝试将该字典还原为Plotly figure对象,此时会用字符串"darkly"去初始化Template类,但Template构造函数要求传入的是字典或Template实例,而非字符串,因此抛出错误。
解决方案

调整顺序:先将原始的Plotly figure对象传给dcc.Graph,再对dcc.Graph组件调用to_plotly_json(),而非先序列化figure。

修改后的generate_pie_charts函数如下:

def generate_pie_charts(df, template) -> list[dict[str, Any]]:
    pie_charts = list()

    for field in df.columns.tolist():
        
        value_count_df = df[field].value_counts().reset_index()        

        cols = value_count_df.columns.tolist()

        name: str = cols[0]
        value: str = cols[1]

        try:
            # 保留原始figure对象,不先转JSON
            figure = px.pie(
                data_frame=value_count_df,
                values=value,
                names=name,
                title=f"Pie chart of {field}",
                template=template,
            )
            # 先创建dcc.Graph,再对组件转JSON
            pie_chart = dcc.Graph(figure=figure).to_plotly_json()
            
            pie_charts.append(pie_chart)
        except Exception as e:
            print(f"Error-1 {e}")
    
    return pie_charts
补充说明

to_plotly_json()方法的作用是将Dash组件或Plotly figure序列化为可JSON存储的字典,适合直接保存或传递。但如果先序列化figure再传给组件,会破坏figure内部对象的结构(比如将Template对象转为字符串),导致组件无法正确解析。正确的做法是让组件直接接收原生的figure对象,再整体序列化组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:17:20