Flask中Plotly图表转JSON遇循环引用错误求助
Flask中Plotly图表转JSON触发循环引用错误的解决
问题详情
在Flask应用中使用Plotly展示DataFrame生成的折线图,DataFrame数据正常(见Figure 1),调用fig.show()可正常显示图表,但执行json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)转换为JSON时,触发以下错误:
Traceback (most recent call last): File "/Users/benjamin/PycharmProjects/sorare-app/webapp.py", line 32, in homepage graph_json = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) File "/Users/benjamin/PycharmProjects/sorare-collect/venv/lib/python3.10/site-packages/dynamodb_json/json_util.py", line 40, in dumps result_ = TypeSerializer().serialize(json.loads(json.dumps(dct, default=json_serial), File "/Users/benjamin/PycharmProjects/sorare-collect/venv/lib/python3.10/site-packages/simplejson/__init__.py", line 412, in dumps **kw).encode(obj) File "/Users/benjamin/PycharmProjects/sorare-collect/venv/lib/python3.10/site-packages/simplejson/encoder.py", line 296, in encode chunks = self.iterencode(o, _one_shot=True) File "/Users/benjamin/PycharmProjects/sorare-collect/venv/lib/python3.10/site-packages/simplejson/encoder.py", line 378, in iterencode return _iterencode(o, 0) ValueError: Circular reference detected
完整代码
leaderboards = football_so5_leaderboards.get_leaderboards_in_group("global-all_star-division-4", dynamodb_client) df = pd.DataFrame(json.loads(leaderboards)) print(df) fig = px.line(df, x = 'so5_fixture_gameweek', y='last_rewarded_score', title='Average Last Rewarded Score', labels={ 'so5_fixture_gameweek': 'Gameweek', 'last_rewarded_score': 'Score' }) fig.show() print(fig) graph_json = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) return render_template('homepage.html', grap_json=graph_json)
Figure 1: DataFrame数据
so5_fixture_gameweek last_rewarded_score 0 298 341.25 1 299 322.81 2 300 0.00 3 301 360.42 4 302 347.76 5 303 0.00 6 304 345.43 7 305 0.00 8 306 0.00 9 307 302.05 10 308 0.00 11 309 296.09 12 310 0.00 13 311 0.00 14 312 0.00 15 313 0.00 16 314 332.46 17 315 353.26 18 316 332.81 19 317 364.27 20 318 342.25 21 319 356.51 22 320 333.90 23 321 333.16
Figure 2: Plotly Figure对象输出
Figure({ 'data': [{'hovertemplate': 'Gameweek=%{x}<br>Score=%{y}<extra></extra>', 'legendgroup': '', 'line': {'color': '#636efa', 'dash': 'solid'}, 'marker': {'symbol': 'circle'}, 'mode': 'lines', 'name': '', 'orientation': 'v', 'showlegend': False, 'type': 'scatter', 'x': array([298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321]), 'xaxis': 'x', 'y': array([341.25, 322.81, 0. , 360.42, 347.76, 0. , 345.43, 0. , 0. , 302.05, 0. , 296.09, 0. , 0. , 0. , 0. , 332.46, 353.26, 332.81, 364.27, 342.25, 356.51, 333.9 , 333.16]), 'yaxis': 'y'}], 'layout': {'legend': {'tracegroupgap': 0}, 'template': '...', 'title': {'text': 'Average Last Rewarded Score'}, 'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'Gameweek'}}, 'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'Score'}}} })
解决方法
1. 使用Plotly内置的to_json()方法
Plotly的Figure对象自带序列化方法,无需手动调用json.dumps,该方法已内置处理循环引用的逻辑,直接替换代码中JSON转换的行:
graph_json = fig.to_json()
2. 排查json模块冲突
从错误栈可见,实际调用的是dynamodb_json.json_util中的dumps方法,而非Python标准库的json模块。如果代码中存在from dynamodb_json import json_util as json这类导入语句,会覆盖标准json模块,导致序列化逻辑冲突。
- 若要继续使用标准库json,需确保导入的是标准模块:
import json graph_json = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder) - 更推荐使用Plotly自带的
to_json(),避免模块冲突问题。
3. 验证模板变量拼写
代码中传递给模板的变量是grap_json,需确保前端模板中使用的变量名完全一致,避免拼写错误导致图表无法渲染。示例前端渲染代码:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> <div id="chart"></div> <script> var graph = {{ grap_json|safe }}; Plotly.newPlot('chart', graph.data, graph.layout); </script>
内容的提问来源于stack exchange,提问作者Contact AllStarSignature
相关产品推荐
相关产品推荐

