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

python将绘图保存到本地文件并插入html,python,plotly,Python,Plotly,我正在使用python和plotly生成交互式html报告。提供了一个很好的框架 如果我在线生成绘图(通过plotly),并将url插入html文件,它可以工作,但刷新图表需要很长时间。我想知道是否可以脱机生成图表并将其嵌入html报告中,这样加载速度就不会有问题了 我发现plot offline会为图表生成一个html,但我不知道如何将它嵌入到另一个html中。任何人都可以提供帮助?选项1:在您的Jupyter笔记本中使用plotly的脱机功能(我假设您使用的是您提供的链接中的Jupyter笔

我正在使用python和plotly生成交互式html报告。提供了一个很好的框架

如果我在线生成绘图(通过plotly),并将url插入html文件,它可以工作,但刷新图表需要很长时间。我想知道是否可以脱机生成图表并将其嵌入html报告中,这样加载速度就不会有问题了


我发现plot offline会为图表生成一个html,但我不知道如何将它嵌入到另一个html中。任何人都可以提供帮助?

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

选项2:最好的方法可能是直接针对plotly的JavaScript库编写代码。相关文档可在以下位置找到:

更新:调用内部函数从来都不是一个好主意。我建议使用@Fermin Silva给出的方法。在较新的版本中,现在还有一个专用的函数:
plotly.io.to_html
(请参阅)

Hacky Option 3(原始版本仅供参考):如果您真的想继续使用Python,可以使用一些hack来提取它生成的HTML。您需要plotly的一些最新版本(我使用
plotly对其进行了测试。\uuuuu version\uuuu=='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文档主体的某个位置。只需确保在头部包含对plotly的引用:

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

或者,您也可以引用用于生成HTML或内联JavaScript源代码的精确plotly版本(这会删除任何外部依赖项;但是要注意法律方面)

您最终会得到如下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>

window.PLOTLYENV=window.PLOTLYENV | |{};window.PLOTLYENV.BASE\u URL=”https://plot.ly";Plotly.newPlot(“7979e646-13e6-4f44-8d32-d8effc3816df”,[{“x”:[1,2,3],“y”:[3,1,6]}],{},{“showLink”:false,“linkText”:“}”)

注意:函数名称开头的下划线表明,
\u plot\u html
不是从外部代码调用的。因此,这段代码很可能会与plotly的未来版本发生冲突。

目前有一个更好的替代方案,即离线打印到div中,而不是完整的html。 此解决方案不涉及任何黑客

如果你打电话:

plotly.offline.plot(data, filename='file.html')
它创建一个名为
file.html
的文件,并在web浏览器中打开它。但是,如果您这样做:

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>

window.PLOTLYENV=window.PLOTLYENV | |{};window.PLOTLYENV.BASE\u URL=”https://plot.ly";绘图。新建绘图(“82072c0d-ba8d-4e86-b000-0892be065ca8”,
[{“y”:..大量数据…,“x”:..大量数据..,{“showlegend”:true,“title”:“title”,“xaxis”:{“zeroline”:true,“showline”:true},
“yaxis”:{“zeroline”:true,“showline”:true,“range”:[0,22.63852380952382]},{“linkText”:“Export to plot.ly”,“showLink”:true})
请注意,它只是html的一小部分,应该嵌入到更大的页面中。为此,我使用了一个标准的模板引擎,如Jinga2

有了它,您可以创建一个html页面,其中包含按您希望的方式排列的多个图表,甚至可以将其作为服务器对ajax调用的响应返回,非常好

更新:

记住,要使所有这些图表正常工作,您需要包含plotly js文件

你可以包括

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> 


就在放置您得到的div之前。如果您将此js放在页面底部,图表将不起作用。

我无法让这些解决方案中的任何一个起作用。我的目标是在一个笔记本中生成绘图,并在另一个笔记本中发布它们,因此持久化绘图HTML对我来说并不像简单地拥有序列化pl的方法那样重要ot到要在其他地方重建的磁盘

我提出的解决方案是将
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')

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

要即兴编写以下代码,您可以调用以下代码,例如:

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()    


除了其他答案外,另一种可能的解决方案是在plotly图上使用
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))
绘图导入
#创建一个简单的绘图
bar=plotly.graph_objs.bar(x=[‘长颈鹿’、‘猩猩’、‘猴子’],
y=[20,14,23])
layout=plotly.graph\u objs.layout()
图=绘图仪对象图([bar],布局)
#将其转换为JSON
fig_json=fig.to_json()
#一个简单的HTML模板
模板=“”“
变量plotly_data={}
Plotly.react('divPlotly',Plotly\u data.data,Plotly\u data.layout);
"""
#将JSON写入HTML模板
以open('new_plot.html','w')作为f:
f、 写入(template.format(fig_json))

您还可以根据问题的答案使用iframe


我最近需要将Plotly图表导出为HTML文件

以下是2019年实现这一目标的简单正确方法

import plotly.offline    
plot(figure, "file.html")

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

import plotly.io as pio
pio.write_html(fig, file='Name.html', auto_open=True)

在重要会议之前,我曾多次使用它来存储我的图表

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

import plotly.io as pio
pio.write_html(fig, file='Name.html', auto_open=True)
fig.write_html("path/to/file.html")
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)
<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>