python保存plotly绘图到本地文件并插入到html中

con*_*001 41 python plotly

我正在使用python和plotly来生成交互式html报告.这篇文章给了一个很好的框架.

如果我在线生成绘图(通过plotly),并将url插入到html文件中,它可以工作,但刷新图表需要很长时间.我想知道我是否可以离线生成图表并将其嵌入到html报告中,因此加载速度不是问题.

我发现离线图会为图表生成一个html,但我不知道如何将它嵌入到另一个html中.有人可以帮忙吗?

Fer*_*lva 117

现在有一个更好的选择,就是离线绘制成div而不是完整的html.此解决方案不涉及任何黑客攻击.

如果你打电话:

plotly.offline.plot(data, filename='file.html')
Run Code Online (Sandbox Code Playgroud)

它会创建一个名为的文件file.html,并在您的Web浏览器中将其打开.但是,如果你这样做:

plotly.offline.plot(data, include_plotlyjs=False, output_type='div')
Run Code Online (Sandbox Code Playgroud)

该调用将返回一个字符串,其中只包含创建数据所需的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>
Run Code Online (Sandbox Code Playgroud)

请注意它只是一小部分html,你应该嵌入一个更大的页面.为此,我使用像Jinga2这样的标准模板引擎.

有了这个,您可以创建一个html页面,其中包含按您想要的方式排列的几个图表,甚至可以将其作为服务器响应返回给ajax调用,非常可爱.

更新:

请记住,您需要包含所有这些图表的plotly js文件才能工作.

你可以包括

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> 
Run Code Online (Sandbox Code Playgroud)

就在把你得到的div之前.如果您将此js放在页面底部,则图表将无法使用.

  • 谢谢.你的答案[这里](http://stackoverflow.com/a/38033016/1185293)包含了关键的一句话,"你可以包括`<script src ="https://cdn.plot.ly/plotly-latest.min .js"> </ script>`就在把你得到的div之前.",这解决了我的问题. (11认同)
  • 我不知道为什么他们在文档中将这些简单的东西作为复活节彩蛋保存。...再加上100个答案!!:) (2认同)

JPW*_*JPW 23

选项1:在Jupyter笔记本中使用plotly的离线功能(我想你正在使用你提供的链接中的Jupyter Notebook).您只需将整个笔记本保存为HTML文件即可.当我这样做时,唯一的外部引用是JQuery; plotly.js将在HTML源代码中内联.

选项2:最好的方法可能是直接针对plotly的JavaScript库进行编码.有关此文档,请访问:https://plot.ly/javascript/

Hacky选项3:如果你真的想继续使用Python,你可以使用一些hack来提取它生成的HTML.你需要一些最新版本的情节(我测试过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)
Run Code Online (Sandbox Code Playgroud)

您只需将输出粘贴到HTML文档正文中的某个位置即可.只需确保在头部包含一个参考:

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

或者,您也可以引用用于生成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>
Run Code Online (Sandbox Code Playgroud)

注意:函数名称开头的下划线表示_plot_html不打算从外部代码调用.因此,这个代码很可能会破坏未来的版本.


Max*_*ers 11

除了其他答案之外,另一种可能的解决方案是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))
Run Code Online (Sandbox Code Playgroud)


Dav*_*arx 7

我无法获得所有这些解决方案。我的目标是在一个笔记本中生成图并在另一个笔记本中发布它们,因此持久保存图HTML对我而言并不重要,只是拥有某种将图序列化到磁盘以在其他地方重建的方法。

我想出的解决方案是将fig对象序列化为JSON,然后使用plotly的“ json图表架构”从JSON构建图。该演示全为python,但如果需要的话,使用此JSON序列化策略在HTML中构建图并直接调用plotly javascript库应该很简单。

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')
Run Code Online (Sandbox Code Playgroud)

编辑:根据相关的github 问题的讨论,这可能是当前的最佳方法。


Ita*_*chi 7

认为答案需要根据最新版本进行更新。(情节== 4.9.0)

fig.write_html("path/to/file.html")
Run Code Online (Sandbox Code Playgroud)

参考:plotly 文档


Var*_*nVk 6

最简单的方法是使用plotly中的pio

import plotly.io as pio
pio.write_html(fig, file='Name.html', auto_open=True)
Run Code Online (Sandbox Code Playgroud)

在重要会议之前我已经大量使用它来存储我的图表