Plotly.offline图的output_type ='div'在HTML内不起作用-如何将Plotly嵌入到HTML [英] Plotly.offline plot output_type='div' not working inside HTML - How to embed Plotly to HTML
问题描述
我创建了一个简单的Flask应用程序,该应用程序呈现了模板"index.html",在该HTML中,我试图将各种图表列为一种具有其他内容的仪表板风格的网页.我不了解Flask和Dash的基础知识,尽管我不使用Dash,因为我想对HTML/CSS拥有更多控制权,因此可以使用Flask创建一个网站来使用Plotly嵌入图形.
I have created a simple Flask app which renders a template 'index.html' and in that HTML I am attempting to list various plots as a sort of dashboard-style webpage with other content. I know the basics of Flask and Dash though am not using Dash as I want to have more control over the HTML/CSS hence using Flask to create a website to embed the graphs using Plotly.
到目前为止,我对任何官方文档,任何media.com或类似文章都没有运气.我最接近的答案是:将破折号图形插入到html
So far I've had no luck with any of the official documentation or any medium.com or suchlike articles. The closest I have come to is this answer: Embedding dash plotly graphs into html
但是,当我运行我的应用程序并且浏览器在localhost中启动时,它不起作用.取而代之的是,它只是给了我很多文字,显然是阴谋的身影,但并没有变成图表.
However, it isn't working when I run my app and the browser launches in localhost. Instead it just gives me a lot of text which is clearly the plotly figure, but it isn't turning into a graph.
这是我所有的py/html/css,即使导航栏的内容无关紧要;以防万一(我仍在学习,所以我敢肯定会有一些更好的方法来做事情.)
Here is all my py/html/css even if the navbar stuff isn't relevant; just in case (I am still learning so I'm sure there will be some better ways to do things..)
感谢您的帮助.
DataFrame类,可获取最新的冠状病毒数据并以pandas.dataframe的形式返回:
DataFrame class which grabs the latest Coronavirus data and returns as pandas.dataframe:
import pandas as pd
import requests
class DataFrame:
"""
Class which grabs the data live from the ECDC and returns it in a pandas dataframe
"""
def __init__(self):
"""
Creating the pandas dataframe of the ECDC JSON data
"""
self.url = "https://opendata.ecdc.europa.eu/covid19/casedistribution/json"
self.file = requests.get(self.url).json()
self.file = self.file['records']
self.df = pd.DataFrame(data=self.file)
def converter(self):
"""
Converting the dtypes from object to int for ints, and date to date
Also renames the columns to more visual-friendly names
:return: None
"""
self.df['cases'] = self.df['cases'].astype(int)
self.df['deaths'] = self.df['deaths'].astype(int)
self.df['popData2018'] = self.df['popData2018'].astype(str).replace('', 0).astype(int)
self.df['dateRep'] = self.df['dateRep'].to_timestamp
cols_rename = 'date day month year cases deaths country geo_id country_id population continent'.split()
cols_rename = [s.capitalize() for s in cols_rename]
self.df.columns = cols_rename
def return_df(self):
"""
:return: pandas DataFrame
"""
self.converter()
return self.df
app.py
from plotly.offline import plot
import plotly.graph_objects as go
from dataframe.dataframe import DataFrame
from flask import Flask, render_template, redirect, request, url_for
app = Flask(__name__)
def graph_maker():
df = DataFrame().return_df()
data = []
for continent in df['Continent'].unique():
df_filt = df[df['Continent'] == continent]
data.append(go.Scatter(x=df_filt["Cases"],
y=df_filt["Deaths"],
mode='markers',
text=df_filt['Country'],
name=continent))
layout = go.Layout(title="Deaths (Y) v Cases (X) by continent")
fig = go.Figure(data=data, layout=layout)
return plot(figure_or_data=fig,
include_plotlyjs=False,
output_type='div')
@app.route('/')
def index():
graph = graph_maker()
return render_template('index.html',
graph=graph)
if __name__ == '__main__':
app.run(debug=True)
index.html
index.html
{% extends "navbar.html" %}
<head>
<meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="..\static\master.css">
<link href="https://fonts.googleapis.com/css2?family=Maven+Pro&display=swap" rel="stylesheet">
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
{% block nbar %}
<body>
<div class="global-box" id="global-stats">
<h1>Global charts</h1>
<p>Title here</p>
<ul class="global-box-ul">
<li class="global-box-ul-li">
{{ graph }}
</li>
<li class="global-box-ul-li">
Another chart here
</li>
</ul>
</div>
</body>
{% endblock %}
navbar.html
navbar.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>C19DB</title>
<meta charset="UTF-8">
<link type="text/css" rel="stylesheet" href="..\static\master.css">
<link href="https://fonts.googleapis.com/css2?family=Maven+Pro&display=swap" rel="stylesheet">
</head>
<nav class="navbar">
<div class="logo">c19db</div>
<div class="list">
<ul class="navbar_items">
<li class="navbar_item"><a href="#">Dashboard</a></li>
<li class="navbar_item"><a href="#">About</a></li>
<li class="navbar_item"><a href="#">Register</a></li>
</ul>
</div>
</nav>
{% block nbar %}
{% endblock %}
</html>
master.css
master.css
html, body {
font-family: 'Maven Pro';
height: 700px;
margin: 0;
}
.navbar {
background: rgb(237, 232, 232);
vertical-align: middle;
}
.logo {
vertical-align: middle;
display: inline-block;
color: rgb(196, 69, 69);
font-size: 50px;
width: 250px;
padding: 5px 15px 5px 15px;
}
.list{
vertical-align: middle;
display: inline-block;
width: calc(100% - 285px);
text-align: right;
}
.navbar_items {
list-style: none;
font-size: 20px;
color: rgb(61, 61, 61)
}
.navbar_item{
display: inline-block;
padding: 5px 15px 5px 15px;
}
a {
text-decoration: none;
}
.navbar_item > a{
display: inline-block;
padding: 5px 15px 5px 15px;
color: rgb(61, 61, 61);
}
.navbar_item > a:hover {
display: inline-block;
padding: 5px 15px 5px 15px;
color: rgb(196, 69, 69);
}
.footer, .footer a {
position: relative;
background: rgb(237, 232, 232, 0.2);
width: 100%;
color: rgb(61, 61, 61, 0.2);
text-align: center;
}
span {
font-weight: bold;
}
.global-box {
text-align: center;
border: 2px black solid;
list-style: none;
margin: auto;
}
.global-box > h1, .global-box > p {
margin: 1px;
}
ul {
display: contents;
}
.global-box-ul-li {
display: inline-block;
border: 2px lightblue solid;
list-style: none;
margin: auto;
width: 48%;
height: 100%;
}
谢谢您的帮助!
推荐答案
我已经解决了这个问题.
I have solved this problem.
果壳:
- 创建图表
- 像往常一样通过无花果,
output_type ='div'
和include_plotlyjs = False
调用 - 将输出输出到通过
Markup()
(从flask导入)传递的变量 - 像通过表格一样,将
Markup(variable)
通过render_template
传递 - 使用
{{jinja template}}
在html中呈现变量
pyo.plot()
- Create a chart
- Call
pyo.plot()
as normal passing through the fig,output_type='div'
andinclude_plotlyjs=False
- Have that output to a variable passed through
Markup()
(import from flask) - Have the
Markup(variable)
passed through therender_template
like you would a form - Have the variable rendered in the html using
{{ jinja template }}
首先,像平常一样创建您的Plotly图表.我不会给出一个完整的例子,而只是关键点.我在函数中创建图表以进行导入,并在必要时在多个页面中使用.在这种情况下,有必要,因为必须将图表分配给变量.
First, create your Plotly chart like normal. I will not give a whole example but just the key points. I create charts in functions for import and use in multiple pages if necessary. In this case, it's necessary because the chart must be assigned to a variable.
def my_bar_chart():
*snip irrelevant*
my_bar_chart = pyo.plot(fig, output_type='div', include_plotlyjs=False)
return Markup(my_bar_chart)
例如,现在将函数导入到app.py/中,无论您的视图在哪里,都可以像使用任何表单一样通过渲染模板进行传递.
Now import your function to your app.py / wherever your views are and pass it through render template as you would any form, for example.
这里是一个例子:
def my_page():
my_bar_chart_var = my_bar_chart()
return render_template('my_page.html',
bar_chart_1=my_bar_chart_var)
然后在该页面的html上像这样在Jinja模板中简单地通过 bar_chart_1
:
Then on the html for that page simply pass through bar_chart_1
in a jinja template like so:
{{ bar_chart_1 }}
完成.
这篇关于Plotly.offline图的output_type ='div'在HTML内不起作用-如何将Plotly嵌入到HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!