我正在使用python和plotly来生成交互式html报告。 This post提供了一个很好的框架。
如果我在线制作绘图(通过绘图),并将网址插入html文件,它可以正常工作,但刷新图表需要很长时间。我想知道我是否可以离线生成图表并将其嵌入到html报告中,因此加载速度不是问题。
我发现离线图会为图表生成一个html,但我不知道如何将其嵌入到另一个html中。有人可以帮忙吗?
答案 0 :(得分:107)
现在还有一个更好的替代方案,那就是离线绘制成div而不是完整的html。 此解决方案不涉及任何黑客攻击。
如果你打电话:
plotly.offline.plot(data, filename='file.html')
它会创建一个名为file.html
的文件,并在您的网络浏览器中将其打开。但是,如果你这样做:
plotly.offline.plot(data, include_plotlyjs=False, output_type='div')
调用将返回一个字符串,其中只包含创建数据所需的div,例如:
<div id="82072c0d-ba8d-4e86-b000-0892be065ca8" style="height: 100%; width: 100%;" class="plotly-graph-div"></div>
<script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("82072c0d-ba8d-4e86-b000-0892be065ca8",
[{"y": ..bunch of data..., "x": ..lots of data.., {"showlegend": true, "title": "the title", "xaxis": {"zeroline": true, "showline": true},
"yaxis": {"zeroline": true, "showline": true, "range": [0, 22.63852380952382]}}, {"linkText": "Export to plot.ly", "showLink": true})</script>
请注意,它只是你应该嵌入更大页面的html的一小部分。为此,我使用像Jinga2这样的标准模板引擎。
有了这个,您可以创建一个html页面,其中包含按您想要的方式排列的多个图表,甚至可以将其作为服务器响应ajax调用返回,非常可爱。
<强>更新强>
请记住,您需要将所有这些图表的plotly js文件包含在内。
你可以包括
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
在放入你得到的div之前。如果您将此js放在页面底部,则图表将无效。
答案 1 :(得分:20)
选项1 :在Jupyter笔记本中使用plotly的离线功能(我想你使用的是你提供的链接中的Jupyter Notebook)。您只需将整个笔记本保存为HTML文件即可。当我这样做时,唯一的外部引用是JQuery; plotly.js将在HTML源代码中内联。
选项2 :最好的方法可能是直接针对plotly的JavaScript库进行编码。有关此文档,请访问:https://plot.ly/javascript/
Hacky Option 3 :如果你真的想继续使用Python,可以使用一些hack来提取它生成的HTML。你需要一些最新版本的plotly(我用plotly.__version__ == '1.9.6'
测试它)。现在,您可以使用内部函数来获取生成的HTML:
from plotly.offline.offline import _plot_html
data_or_figure = [{"x": [1, 2, 3], "y": [3, 1, 6]}]
plot_html, plotdivid, width, height = _plot_html(
data_or_figure, False, "", True, '100%', 525)
print(plot_html)
您只需将输出粘贴到HTML文档正文中的某个位置即可。只需确保在头部包含一个参考:
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
或者,您也可以引用用于生成HTML的精确绘图版本或内联JavaScript源代码(删除任何外部依赖项;但请注意法律方面)。
您最终得到了一些HTML代码:
<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<!-- Output from the Python script above: -->
<div id="7979e646-13e6-4f44-8d32-d8effc3816df" style="height: 525; width: 100%;" class="plotly-graph-div"></div><script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("7979e646-13e6-4f44-8d32-d8effc3816df", [{"x": [1, 2, 3], "y": [3, 1, 6]}], {}, {"showLink": false, "linkText": ""})</script>
</body>
</html>
注意:函数名称开头的下划线表示_plot_html
并不打算从外部代码调用。因此,这个代码可能会破坏未来版本的情节。
答案 2 :(得分:5)
我无法使这些解决方案起作用。我的目标是在一个笔记本中生成绘图并将它们发布到另一个笔记本中,因此对于我而言,持续存在HTML并不像仅仅使用一些方法将绘图序列化到磁盘以在其他地方重建。
我想出的解决方案是将import numpy as np
import json
from plotly.utils import PlotlyJSONEncoder
from plotly.offline import download_plotlyjs, init_notebook_mode, iplot
import plotly.graph_objs as go
init_notebook_mode()
def plotlyfig2json(fig, fpath=None):
"""
Serialize a plotly figure object to JSON so it can be persisted to disk.
Figures persisted as JSON can be rebuilt using the plotly JSON chart API:
http://help.plot.ly/json-chart-schema/
If `fpath` is provided, JSON is written to file.
Modified from https://github.com/nteract/nteract/issues/1229
"""
redata = json.loads(json.dumps(fig.data, cls=PlotlyJSONEncoder))
relayout = json.loads(json.dumps(fig.layout, cls=PlotlyJSONEncoder))
fig_json=json.dumps({'data': redata,'layout': relayout})
if fpath:
with open(fpath, 'wb') as f:
f.write(fig_json)
else:
return fig_json
def plotlyfromjson(fpath):
"""Render a plotly figure from a json file"""
with open(fpath, 'r') as f:
v = json.loads(f.read())
fig = go.Figure(data=v['data'], layout=v['layout'])
iplot(fig, show_link=False)
## Minimial demo ##
n = 1000
trace = go.Scatter(
x = np.random.randn(n),
y = np.random.randn(n),
mode = 'markers')
fig = go.Figure(data=[trace])
#iplot(fig)
plotlyfig2json(fig, 'myfile.json')
plotlyfromjson('myfile.json')
对象序列化为JSON,然后使用plotly的“json图表模式”从JSON构建图。这个演示都是python,但使用这个JSON序列化策略在HTML中构建一个绘图并直接调用plotly javascript库应该是微不足道的,如果这就是你需要的。
ListViewItem _result = null;
public ListViewItem Result { get { return _result; } }
public List<ListViewItem> Source
{
set
{
listView1.Items.Clear();
foreach (ListViewItem item in value)
listView1.Items.Add(item);
listView1.View = View.List;
}
}
private void button1_Click(object sender, EventArgs e)
{
if (_result == null)
return;
DialogResult = DialogResult.OK;
Close();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
ListView list = (ListView)sender;
ListView.SelectedIndexCollection indices = list.SelectedIndices;
if (indices.Count == 0)
return;
_result = list.Items[indices[0]];
}
编辑:关于相关github issue的讨论,这可能是目前最好的方法。
答案 3 :(得分:4)
答案 4 :(得分:2)
最简单的方法是从地上使用 pio
import plotly.io as pio
pio.write_html(fig, file='Name.html', auto_open=True)
在重要会议之前,我已经大量使用它来存储图形了
答案 5 :(得分:1)
您还可以根据问题how to embed html into ipython output的答案使用iframe吗?
plotly.offline.plot(fig, filename='figure.html',validate=False)
from IPython.display import IFrame
IFrame(src='./figure.html', width=1000, height=600)
答案 6 :(得分:1)
在 Plotly 5 中(也可能在 4 中),BaseFigure.to_html
具有 include_plotlyjs
参数,默认情况下为 True
。
指定如何在输出 div 字符串中包含/加载 plotly.js
库。
如果为 True
,则输出中包含包含 plotly.js
源代码 (~3MB) 的脚本标记。使用此选项生成的 HTML 文件是完全独立的,可以离线使用。
有趣的是,可以在此处使用 Pyodide 说明 Plotly 图 HTML 嵌入。
const plotlyScript = `
import plotly.express as px
fig = px.bar(y=[0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
fig.to_html(full_html=False)
`
async function main() {
const pyodideUrl = 'https://cdn.jsdelivr.net/pyodide/v0.17.0/full/'
const pyodide = await loadPyodide({'indexURL': pyodideUrl})
await pyodide.loadPackage(['pandas']) // needed for plotly
const html = await pyodide.runPythonAsync(plotlyScript)
const fragment = document.createRange().createContextualFragment(html)
const output = document.getElementById('plotly-output')
output.textContent = ''
output.append(fragment)
}
main()
<script type="text/javascript" src="https://cdn.jsdelivr.net/pyodide/v0.17.0/full/pyodide.js"></script>
<div id="plotly-output">Loading pyodide... It may take a minute.</div>
答案 7 :(得分:0)
为了简化下面的代码,您可以调用,例如ex_的to_plotly_json()
def plotlyfig2json(fig, fpath=None):
"""
Serialize a plotly figure object to JSON so it can be persisted to disk.
Figures persisted as JSON can be rebuilt using the plotly JSON chart API:
http://help.plot.ly/json-chart-schema/
If `fpath` is provided, JSON is written to file.
Modified from https://github.com/nteract/nteract/issues/1229
"""
redata = json.loads(json.dumps(fig.data, cls=PlotlyJSONEncoder))
relayout = json.loads(json.dumps(fig.layout, cls=PlotlyJSONEncoder))
fig_json=json.dumps({'data': redata,'layout': relayout})
if fpath:
with open(fpath, 'wb') as f:
f.write(fig_json)
else:
return fig_json
--------------------------------------------
Simple way:
fig = go.Figure(data=['data'], layout=['layout'])
fig.to_plotly_json()
答案 8 :(得分:0)
除了其他答案外,另一种可能的解决方案是在绘图上使用to_json()
。
无需自定义JSON序列化程序或使用内部解决方案。
import plotly
# create a simple plot
bar = plotly.graph_objs.Bar(x=['giraffes', 'orangutans', 'monkeys'],
y=[20, 14, 23])
layout = plotly.graph_objs.Layout()
fig = plotly.graph_objs.Figure([bar], layout)
# convert it to JSON
fig_json = fig.to_json()
# a simple HTML template
template = """<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id='divPlotly'></div>
<script>
var plotly_data = {}
Plotly.react('divPlotly', plotly_data.data, plotly_data.layout);
</script>
</body>
</html>"""
# write the JSON to the HTML template
with open('new_plot.html', 'w') as f:
f.write(template.format(fig_json))
答案 9 :(得分:0)
我最近需要将绘图图表导出为HTML文件。
这是在2019年实现的简单正确的方法。
import plotly.offline
plot(figure, "file.html")
答案 10 :(得分:0)
如果你想在 HTML 中插入 fig (go.Figure),也许你应该尝试使用它。
注意:fig 是 go 的一个实例。Figure 和 fig 包含您的情节。
import json
import plotly.graph_objects as go
# step 1 convert fig to json
data = fig.to_json() #return one string
# step 2, save data in the file
filename = 'name_file.json'
with open ('' + filename + 'w') as file:
json.dump(data, file, indent=4)
之后你就可以在 HTML 代码中插入 json 文件了,但是你应该插入依赖项。
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>