【问题标题】:How to plot Plotly Chart on React from JSON response from Flask API?如何根据来自 Flask API 的 JSON 响应在 React 上绘制 Plotly 图表?
【发布时间】:2022-08-06 17:15:26
【问题描述】:

我最近阅读了有关能够使用 Flask 和 JS <script> 标签从 Python 绘制 Plotly 图形的信息,并希望使用 React 和 Flask 作为 API 而不是 vanilla JS 来复制它。获取数据很好,但尝试从 Python Plotly 将其绘制成 JSON -> Plotly on React 将永远无法工作 - 它只会返回一个空白的白色显示。

这是 Flask 端 API 的代码(我刚刚使用来自this example/plot1 函数对其进行测试;JSON 返回正常):

from flask import Flask
import pandas as pd
import json
import plotly
import plotly.express as px

app = Flask(__name__)

@app.route(\'/chart1\')
def chart1():
    df = pd.DataFrame({
        \"Fruit\": [\"Apples\", \"Oranges\", \"Bananas\", \"Apples\", \"Oranges\", \"Bananas\"],
        \"Amount\": [4, 1, 2, 2, 4, 5],
        \"City\": [\"SF\", \"SF\", \"SF\", \"Montreal\", \"Montreal\", \"Montreal\"]
    })

    fig = px.bar(df, x=\"Fruit\", y=\"Amount\", color=\"City\", barmode=\"group\")
    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    return graphJSON

这是我的App.js

import React, { useState, useEffect } from \'react\';
import Plotly from \'plotly.js-dist-min\';
import logo from \'./logo.svg\';
import \'./App.css\';

function App() {

  const [plot, setPlot] = useState(0);

  useEffect(() => {
    fetch(\'/plot\').then(res => res.json()).then(data => {setPlot(data);});}, []);

  Plotly.newPlot(\"graph-div\", plot, {})

  return (
    <div className=\"App\">
      <header className=\"App-header\">
        <img src={logo} className=\"App-logo\" alt=\"logo\" />
        <div id=\"graph-div\" className=\"graph-div\">
        </div>
      </header>
    </div>
  );
}

接收数据时似乎存在某种问题,但我不确定到底是什么问题 - 我在接收数据时遵循与 React-Flask 教程相同的格式并将其绘制为 Flask -Plotly 的例子。有人可以让我知道如何解决这个问题吗?

    标签: reactjs flask plotly-python plotly.js


    【解决方案1】:

    我建议你使用react-plotly.js (https://plotly.com/javascript/react/) 而不是纯plotly.js。您可以将绘图创建为 React 组件;

    这是如何通过react-plotly.js 使用graphJSON.json 文件中的数据和布局创建简单绘图的示例。

    graphJSON.json文件内容:

    {
      "data": [
            {
              "x": [1, 2, 3],
              "y": [2, 6, 3],
              "type": "scatter",
              "mode": "lines+markers",
              "marker": {
                  "color": "red"
              }
            },
            {
              "type": "bar", 
              "x": [1, 2, 3], 
              "y": [2, 5, 3]
          }
      ],
      "layout": {
          "title": "A Fancy Plot"
      } 
    }
    

    React 文件:

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import Plot from 'react-plotly.js';
    import graphJSON from './graphJSON.json';
    
    function App(){
      return(
        <Plot data={json.data} layout={json.layout}/>
      )
    }
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    root.render(
      <App />
    );
    

    您可以直接导入由 Python 脚本生成的 JSON 文件。它是带有数组的对象,您可以通过像属性一样访问它们来使用它们。在我们的例子中:graphJSON.data(如果你想访问数据数组)

    结果:

    【讨论】:

    • 谢谢!我会尝试使用 React Plotly。但是,我打算不断更新的数字,所以最好使用 Flask 来处理它而不是设置多个脚本/crons/等。是否可以直接从 Flask 获取数据?
    • 我还没有使用过 Flask,但如果你想不断更新图表数据,请使用 JSON serwer 或类似 API 之类的工具来刷新绘图数据。 React-Plotly 支持更新事件,因此您可能会在文档中找到答案。
    【解决方案2】:

    我想为任何感兴趣的人更新这篇文章 - 我能够显示 Plotly 图表。

    事实证明,使用 json.dumps 函数未正确发送数据。相反,请使用 Plotly 提供的 plot to JSON 函数。

    更新代码:

    api.py:

    import time, json
    from flask import Flask
    import pandas as pd
    import plotly
    import plotly.express as px
    
    app = Flask(__name__)
    
    @app.route('/time')
    def get_current_time():
        return {'time': time.time()}
        
    @app.route('/plot')
    def plot_test():
        df = pd.DataFrame({
            "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
            "Amount": [4, 1, 2, 2, 4, 5],
            "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
        })
        fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
        graphJSON = plotly.io.to_json(fig, pretty=True)
        return graphJSON
    

    App.js:

    import React, { useState, useEffect } from 'react';
    import Plot from 'react-plotly.js';
    
    const Fund = () => {
        const [plot, setPlot] = useState(0);
        
        useEffect(() => {
          fetch('/plot').then(res => res.json()).then(data => {setPlot(data);});}, []);
          console.log(plot)
        
        return (
          <div className='content'>
          <h1>Current Fund</h1>
          <Plot data={plot.data} layout={plot.layout}/>
          </div>
        );
    };
    
    export default Fund;
    

    【讨论】:

      猜你喜欢
      • 2020-01-11
      • 2021-01-06
      • 2021-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-06
      相关资源
      最近更新 更多