英文:
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('/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)
I have my HTML file, chartsajax.HTML, that is being displayed:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-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>
<!-- end snippet -->
Here is a screen shot of the directory structure within my local host:
When I start the local server:
After I add: localhost:8000/chartsajax.html
to the web address bar, everything is fine:
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.
When I add United Kingdom to the input field, I get a 404 error:
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:
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('/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)
After refactoring, your app is working fine, and showing the plot as below:
screenshot of running app.py
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论