jupyter-notebook - 使用 nbconvert 将笔记本导出为 HTML 并为面板(散景、holoviews、hvplot)嵌入数据
问题描述
我正在尝试将笔记本导出为 HTML,笔记本内部有多个交互式面板。
import panel as pn
import hvplot as hv
import holoviews as hv2
from bokeh.io import output_notebook, push_notebook, show, save, output_file
from bokeh.resources import INLINE
def plot_ts(feature=Spends[0], target=Target[0]):
fig = df[target].plot.line(title=target)
fig += df[feature].plot.area(title=feature)
return fig.cols(1)
kw = dict(feature=sorted(list(Spends + Misc)))
panel1 = pn.interact(plot_ts, **kw)
panel1
现在我正在运行以下行:
!jupyter nbconvert --to html index.ipynb --no-input --no-prompt
问题是我的面板变得陈旧(相应的数据未嵌入其中)。
如果我使用以下行一一保存面板,我将获得带有嵌入数据的面板。
panel1.save('test.html', embed=True, resources=INLINE)
我尝试以这种方式保存所有面板,然后使用 Selenium 合并不同的 HTML 文件,但它不起作用。
我尝试将面板附加到彼此
all_panels.append(panel1).append(panel2).append(panel3)
all_panels.save("all_panels.html", embed=True)
生成的 HTML 文件有问题,一些面板可以工作,而另一些则不能。
如果有人对如何使这项工作有任何想法,那将是惊人的。
谢谢
解决方案
使用 BeautifulSoup,我设法创建了一个 HTML 文件,其中包含保存为独立 html 文件及其嵌入数据的不同面板。
我认为它可能对其他人有用,所以这里是代码:
# Imports
from bs4 import BeautifulSoup, Tag
import glob
# List the filepaths corresponding to panels exported to html using 'panel_object.save("panel_name.html", embed=True)'
panels = glob.glob("/Users/username/Documents/data_exploration/panels/*.html")
panels_soup = []
# Read files and append their soup to a list
for panel in panels:
with open(panel) as fp:
panel = BeautifulSoup(fp, 'html.parser')
panels_soup.append(panel)
# HTML base
soup = BeautifulSoup()
html = soup.new_tag("html")
soup.append(html)
# Append the head tag of one of the panels (it includes the bokeh/holoviews scripts)
soup.html.append(panels_soup[0].find("head"))
# Append an empty body tag
body = soup.new_tag("body")
soup.html.append(body)
# Loop on soups
for panel in panels_soup:
divs = panel.find_all("div", attrs={"class":"bk-root"})
data = panel.find_all('script')[-2]
script = panel.find_all('script')[-1]
panels_dict.append({"div_1":divs[0], "div_2":divs[-1], "data":data, "script":script})
# Append panels divs to the body of the page
for panel in panels_dict:
soup.body.insert(1, panel["div_2"])
soup.body.insert(1, panel["div_1"])
# Append the data at the end of the page
for panel in panels_dict:
soup.body.insert(len(soup.body.contents), panel["data"])
# Append the scripts at the end of the page
for panel in panels_dict:
soup.body.insert(len(soup.body.contents), panel["script"])
# Export HTML file containing all the panels
with open("index.html", "w") as fp:
fp.write(soup.prettify(formatter="html"))
推荐阅读
- javascript - JavaScript | 范围 | 选择 - 有没有办法用 Javascript 来“取消粗体”、“单斜体”和 Range 的内容编辑?
- asp.net-core - 无法创建“DataContext”类型的对象。对于设计时支持的不同模式
- c# - 在 C# 中声明“字符串”变量的最佳方法是什么?
- python - AWS-Lambda:如何在 python 中处理 SNS 事件
- c++ - 如何确定向量长度以确保向量化过程中没有向量依赖性?
- python - Anaconda Python,如何获取 groupby 的值而不仅仅是打印语句?
- haskell - 如何从 Haskell 中的长度生成跨度?
- python - 如何编译使用 sqlalchemy 的 pyqt 脚本?
- regex - 只选择大写句子
- python - ARIMA 可逆性