Flask/Dash生成图表通过AJAX在HTML显示异常的排查求助
问题描述
尝试开发基于Flask/Dash的应用,将生成的图表展示在HTML页面,但点击按钮后图表显示为空,控制台出现两个错误:
plotly-latest.min.js:20 GET http://127.0.0.1:5000/[object Object] 404 (NOT FOUND)plotly-latest.min.js:61 WARN: Calling Plotly.plot as if redrawing but this container doesn't yet have a plot.
现有代码
init.py
# Create a Flask app server = Flask(__name__) bootstrap = Bootstrap5(server) # Define a route to generate the Dash graph @server.route('/create_graph', methods=['POST', 'GET']) def get_graph(): # Define some sample data x_values = [1, 2, 3, 4, 5] y_values = [1, 4, 9, 16, 25] # Create a graph using the data graph = dcc.Graph( id='example-graph', figure={ 'data': [ {'x': x_values, 'y': y_values, 'type': 'line', 'name': 'Example Graph'} ], 'layout': { 'title': 'Example Dash Graph' } } ) # Convert the graph to a JSON string and return it return json.dumps(graph, cls=plotly.utils.PlotlyJSONEncoder) # Define a route to render the HTML template that contains the JavaScript code and the container div for the graph @server.route('/') def index(): return render_template('index.html') # Run the app if __name__ == '__main__': server.run(debug=True)
script.js
$("#test").click(function () { var data_input = ['a', 'b', 'c', 'd']; $.ajax({ type: "POST", url: "/create_graph", data: JSON.stringify(data_input), contentType: "application/json", dataType: 'json', success: function (data) { console.log(data); var graph = Plotly.d3.json(data, function (data) { Plotly.newPlot('graph-location-1', data); }); }, }) })
修复方案
错误核心原因
- 后端错误:直接序列化
dcc.Graph组件返回,但它是Dash的React组件,包含大量非Plotly渲染所需的冗余属性,并非纯图表数据对象。 - 前端错误:
Plotly.d3.json()用于加载远程JSON文件,你传入已解析的JSON对象时,它会将对象转成[object Object]当作URL发起请求,导致404;同时传入Plotly.newPlot的参数格式不符合要求。
修复后代码
修改init.py
只返回纯Plotly figure对象,而非Dash组件:
# Create a Flask app server = Flask(__name__) bootstrap = Bootstrap5(server) # Define a route to generate the Dash graph @server.route('/create_graph', methods=['POST', 'GET']) def get_graph(): # Define some sample data x_values = [1, 2, 3, 4, 5] y_values = [1, 4, 9, 16, 25] # 直接创建Plotly figure对象 figure = { 'data': [ {'x': x_values, 'y': y_values, 'type': 'line', 'name': 'Example Graph'} ], 'layout': { 'title': 'Example Dash Graph' } } # 序列化figure返回 return json.dumps(figure, cls=plotly.utils.PlotlyJSONEncoder) # Define a route to render the HTML template @server.route('/') def index(): return render_template('index.html') # Run the app if __name__ == '__main__': server.run(debug=True)
修改script.js
直接使用返回的figure对象渲染,无需调用Plotly.d3.json:
$("#test").click(function () { var data_input = ['a', 'b', 'c', 'd']; $.ajax({ type: "POST", url: "/create_graph", data: JSON.stringify(data_input), contentType: "application/json", dataType: 'json', success: function (figure) { console.log(figure); // 直接传入完整figure渲染 Plotly.newPlot('graph-location-1', figure); }, }) })
替代方案:直接在模板中嵌入图表
如果不想手动处理AJAX,可直接在Flask路由生成图表HTML,嵌入模板:
- 后端代码修改:
from plotly.offline import plot @server.route('/') def index(): x_values = [1,2,3,4,5] y_values = [1,4,9,16,25] figure = { 'data': [{'x': x_values, 'y': y_values, 'type': 'line'}], 'layout': {'title': 'Example Graph'} } # 生成图表的HTML片段 graph_html = plot(figure, output_type='div', include_plotlyjs=False) return render_template('index.html', graph_html=graph_html)
- 模板index.html中渲染:
<div>{{ graph_html|safe }}</div> <!-- 页面引入Plotly.js --> <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
内容的提问来源于stack exchange,提问作者Martijn Siepel
相关产品推荐
相关产品推荐

