我最近发现 plotly 并发现它非常适合绘图,现在我有一个问题,我想将多个 plot 保存到一个 html 中,请问如何做?
*我想保存多个图,即图、图 1、图 2 等,而不是一个包含多个图的子图,因为我发现子图中的图太小了。
在 Plotly API 中有一个函数
to_html
返回图形的 HTML。此外,您可以设置选项参数full_html=False
,这将为您提供包含数字的DIV。
您可以通过附加包含图形的 DIV 将多个图形写入一个 HTML:
with open('p_graph.html', 'a') as f:
f.write(fig1.to_html(full_html=False, include_plotlyjs='cdn'))
f.write(fig2.to_html(full_html=False, include_plotlyjs='cdn'))
f.write(fig3.to_html(full_html=False, include_plotlyjs='cdn'))
https://plot.ly/python-api-reference/generated/plotly.io.to_html.html
您还可以使用 Beautiful Soup 进行 DOM 操作,并在 HTML 中将 DIV 准确插入您需要的位置。
这取决于你如何构建html页面。如果它来自 plotly.offline.plot(fig, filename='name.html') 则不可能。 正如您提到的,子图太小,您可以在布局中玩高度和重量可变的游戏:
布局上:
from plotly.offline import plot
from plotly.subplots import make_subplots
import plotly.graph_objects as go
fig = make_subplots(
rows=3, cols=1, shared_xaxes=True,
vertical_spacing=0.02)
fig.add_trace(go.Scatter(x=[0, 1, 2], y=[10, 11, 12]),
row=3, col=1)
fig.add_trace(go.Scatter(x=[2, 3, 4], y=[100, 110, 120]),
row=2, col=1)
fig.add_trace(go.Scatter(x=[3, 4, 5], y=[1000, 1100, 1200]),
row=1, col=1)
fig.update_layout(height=1200, width=600,
title_text="Stacked Subplots with Shared X-Axes")
fig['layout']['yaxis1'].update(domain=[0, 0.2])
fig['layout']['yaxis2'].update(domain=[0.3, 0.7])
fig['layout']['yaxis3'].update(domain=[0.8, 1])
plotly.offline.plot(fig, filename='name.html')
如果您自己构建 html 页面,您可以将 html div 呈现为 http://www.codingwithricky.com/2019/08/28/easy-django-plotly/ 并播放布局的高度和宽度变量以使它变大或变小。
这是一个看起来不错的例子:
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.figure_factory as ff
import numpy as np
import plotly
y1 = np.random.randn(200) - 1
y2 = np.random.randn(200)
y3 = np.random.randn(200) + 1
x = np.linspace(0, 1, 200)
colors = ['#3f3f3f', '#00bfff', '#ff7f00']
fig = make_subplots(
rows=3, cols=2,
column_widths=[0.55, 0.45],
row_heights=[1., 1., 1.],
specs=[[{"type": "scatter"}, {"type": "xy"}],
[{"type": "scatter"}, {"type": "xy", "rowspan": 2}],
[{"type": "scatter"}, None ]])
fig.add_trace(
go.Scatter(x = x,
y = y1,
hoverinfo = 'x+y',
mode='lines',
line=dict(color='#3f3f3f',
width=1),
showlegend=False,
),
row=1, col=1
)
fig.add_trace(
go.Scatter(x = x,
y = y2,
hoverinfo = 'x+y',
mode='lines',
line=dict(color='#00bfff',
width=1),
showlegend=False,
),
row=2, col=1
)
fig.add_trace(
go.Scatter(x = x,
y = y3,
hoverinfo = 'x+y',
mode='lines',
line=dict(color='#ff7f00',
width=1),
showlegend=False,
),
row=3, col=1
)
boxfig= go.Figure(data=[go.Box(x=y1, showlegend=False, notched=True, marker_color="#3f3f3f", name='3'),
go.Box(x=y2, showlegend=False, notched=True, marker_color="#00bfff", name='2'),
go.Box(x=y3, showlegend=False, notched=True, marker_color="#ff7f00", name='1')])
for k in range(len(boxfig.data)):
fig.add_trace(boxfig.data[k], row=1, col=2)
group_labels = ['Group 1', 'Group 2', 'Group 3']
hist_data = [y1, y2, y3]
distplfig = ff.create_distplot(hist_data, group_labels, colors=colors,
bin_size=.2, show_rug=False)
for k in range(len(distplfig.data)):
fig.add_trace(distplfig.data[k],
row=2, col=2
)
fig.update_layout(barmode='overlay')
plotly.offline.plot(fig, filename='test.html')
#fig.show()
建立在@mil0s answer的基础上,这里有一个小函数,它获取多个 plotly 图像并将它们组合成一个 html 文件,它们之间可能有一个分隔符,以及一个像 plotly 一样的自动打开功能:
def combine_plotly_figs_to_html(plotly_figs, html_fname, include_plotlyjs='cdn',
separator=None, auto_open=False):
with open(html_fname, 'w') as f:
f.write(plotly_figs[0].to_html(include_plotlyjs=include_plotlyjs))
for fig in plotly_figs[1:]:
if separator:
f.write(separator)
f.write(fig.to_html(full_html=False, include_plotlyjs=False))
if auto_open:
import pathlib, webbrowser
uri = pathlib.Path(html_fname).absolute().as_uri()
webbrowser.open(uri)