Displaying a figure on web browser, based on user input, using Python Flask

huangapple go评论65阅读模式
英文:

Displaying a figure on web browser, based on user input, using Python Flask

问题

以下是您提供的代码的翻译部分:

我想在我的Web浏览器上显示一个Plotly图表根据用户输入使用Python Flask我使用Python - HTTP Server运行以下命令

python -m http.server

我有一个名为app.py的文件用于Python代码和路由

    from flask import Flask, config, render_template, request
    from flask_cors import CORS, cross_origin
    import pandas as pd
    import json
    import plotly
    import plotly.express as px
    
    
    app = Flask(__name__)
    CORS(app)
    @cross_origin()
    
    @app.route('/callback', methods=['POST', 'GET'])
    def cb():
        return gm(request.args.get('data'))
       
    @app.route('/')
    def index():
        return render_template('localhost:8000/chartsajax.html',  graphJSON=gm())
    
    def gm(country='United Kingdom'):
        df = pd.DataFrame(px.data.gapminder())
        fig = px.line(df[df['country']==country], x="year", y="gdpPercap")
        graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    
        return graphJSON
    
    if __name__ == '__main__':
        app.run(host='localhost', port=8000, debug=False)
我有一个HTML文件,名为chartsajax.HTML,正在显示:

<!doctype html>
<html>
<head>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
        function cb(selection) {
            $.getJSON({
                url: "/callback", data: { 'data': selection }, success: function (result) {
                    Plotly.react('chart', result, {});;
                }
            });
        }
    </script>
</head>

<body style="font-family:arial, sans-serif">
    <h1>GDP per Capita Over Time</h1>
    <h2>Choose your country</h2>
    <p>Make sure you spell it correctly with capital letter(s), e.g. United Kingdom</p>
    <input type="text" id="fname" name="fname" onchange="cb(this.value)">
    <div id="chart" class="chart"></div>
    <div id="png_chart"></div>
</body>

<script>
    cb("United Kingdom");
</script>
</html>

希望这可以帮助您解决代码的问题。

英文:

I want to display a Plotly figure on my web browser, based on user input, using python flask. I am using "Python - HTTP Server" and I run the command:

python -m http.server

I have app.py that I use for the python code and routes:

from flask import Flask, config, render_template, request
from flask_cors import CORS, cross_origin
import pandas as pd
import json
import plotly
import plotly.express as px


app = Flask(__name__)
CORS(app)
@cross_origin()

@app.route(&#39;/callback&#39;, methods=[&#39;POST&#39;, &#39;GET&#39;])
def cb():
    return gm(request.args.get(&#39;data&#39;))
   
@app.route(&#39;/&#39;)
def index():
    return render_template(&#39;localhost:8000/chartsajax.html&#39;,  graphJSON=gm())

def gm(country=&#39;United Kingdom&#39;):
    df = pd.DataFrame(px.data.gapminder())
    fig = px.line(df[df[&#39;country&#39;]==country], x=&quot;year&quot;, y=&quot;gdpPercap&quot;)
    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)

    return graphJSON

if __name__ == &#39;__main__&#39;:
    app.run(host=&#39;localhost&#39;, port=8000, debug=False)

I have my HTML file, chartsajax.HTML, that is being displayed:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;script src=&quot;https://cdn.plot.ly/plotly-latest.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;script&gt;
        function cb(selection) {
            $.getJSON({
                url: &quot;/callback&quot;, data: { &#39;data&#39;: selection }, success: function (result) {
                    Plotly.react(&#39;chart&#39;, result, {});;
                }
            });

            
        }
    &lt;/script&gt;
&lt;/head&gt;

&lt;body style=&quot;font-family:arial, sans-serif&quot;&gt;
    &lt;h1&gt;GDP per Capita Over Time&lt;/h1&gt;
    &lt;h2&gt;Choose your country&lt;/h2&gt;
    &lt;p&gt;Make sure you spell it correctly with capital letter(s), e.g. United Kingdom&lt;/p&gt;
    &lt;input type=&quot;text&quot; id=&quot;fname&quot; name=&quot;fname&quot; onchange=&quot;cb(this.value)&quot;&gt;
    &lt;div id=&quot;chart&quot; class=&quot;chart&quot;&gt;&lt;/div&gt;
    &lt;div id=&quot;png_chart&quot;&gt;&lt;/div&gt;
&lt;/body&gt;

&lt;script&gt;
    cb(&quot;United Kingdom&quot;);
&lt;/script&gt;
&lt;/html&gt;

<!-- end snippet -->

Here is a screen shot of the directory structure within my local host:

Displaying a figure on web browser, based on user input, using Python Flask

When I start the local server:

Displaying a figure on web browser, based on user input, using Python Flask

After I add: localhost:8000/chartsajax.html
to the web address bar, everything is fine:

Displaying a figure on web browser, based on user input, using Python Flask

Displaying a figure on web browser, based on user input, using Python Flask

But, when I add: http://localhost:8000/chartsajax.html
I get the HTML page displaying the field that text need to be entered into to get the plot to show. But, I get a 304 error.

Displaying a figure on web browser, based on user input, using Python Flask

When I add United Kingdom to the input field, I get a 404 error:

Displaying a figure on web browser, based on user input, using Python Flask

I have been trying every combination of code I know to use but cant get the plot to show. I feel like its either directory structure related or something going on with request.args.get('data'). Any input would be greatly appreciated! TIA!

Edit:

After taking Arif's advice and adding a templates folder to the app.py directory, and pasting:

C:/Users/......./Plotly_API/templates/chartsajax.html

into the web address field, I get two errors:

Displaying a figure on web browser, based on user input, using Python Flask

These errors, from early on, when building the code, is why I switched over to using "Python - HTTP Server". That got rid of the error messages but created the other problems, above, in this post.

Edit 2:

Everything Arif suggested worked after I added:

localhost:8000

to the web address field.

Thanks, Arif!

答案1

得分: 0

首先,你的HTML文件应该放在一个名为"templates"的目录内,以便Flask可以正确渲染。在与app.py相同的目录中创建一个名为"templates"的文件夹,然后将HTML文件放入"templates"文件夹中。

现在,当你运行服务器时,不要再输入"python -m http.server",而是在终端中输入"python app.py"。

使用"python -m http.server"来启动一个简单的HTTP服务器是错误的用法,因为它会从当前工作目录中提供文件,这与你的Flask应用程序是分开的。

另外,在以下部分重构你的代码:

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

app = Flask(__name__)

@app.route('/callback', methods=['POST', 'GET'])
def cb():
    return gm(request.args.get('data'))

@app.route('/')
def index():
    return render_template('chartsajax.html', graphJSON=gm())

def gm(country='United Kingdom'):
    df = pd.DataFrame(px.data.gapminder())
    fig = px.line(df[df['country'] == country], x="year", y="gdpPercap")
    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    return graphJSON

if __name__ == '__main__':
    app.run(host='localhost', port=8000, debug=False)

重构后,你的应用程序应该正常运行,并显示如下图所示的图表:
运行app.py的屏幕截图

英文:

Firstly, your html file should be inside a directory named "templates" for flask to render properly. Create a folder named "templates" inside the same directory as app.py, and then keep your html file inside the templates folder.

Now, when you run the server instead of typing "python -m http.server", type "python app.py" in the terminal.

Using "python -m http.server" to start a simple HTTP server is an incorrect usage of the Flask app, as it serves the files from the current working directory, which is separate from your Flask application.

Also, refactor your code in the following section:

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

app = Flask(__name__)

@app.route(&#39;/callback&#39;, methods=[&#39;POST&#39;, &#39;GET&#39;])
def cb():
    return gm(request.args.get(&#39;data&#39;))

@app.route(&#39;/&#39;)
def index():
    return render_template(&#39;chartsajax.html&#39;, graphJSON=gm())

def gm(country=&#39;United Kingdom&#39;):
    df = pd.DataFrame(px.data.gapminder())
    fig = px.line(df[df[&#39;country&#39;] == country], x=&quot;year&quot;, y=&quot;gdpPercap&quot;)
    graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    return graphJSON

if __name__ == &#39;__main__&#39;:
    app.run(host=&#39;localhost&#39;, port=8000, debug=False)

After refactoring, your app is working fine, and showing the plot as below:
screenshot of running app.py

huangapple
  • 本文由 发表于 2023年5月18日 06:03:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276476.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定