我正在尝试以编程方式生成一个notebook,执行它,并使用nbformat转换为HTML。
代码基本上是这样的:
import nbformat as nbf
from nbconvert.preprocessors import ExecutePreprocessor
from nbconvert import HTMLExporter
nb = nbf.v4.new_notebook()
nb.cells = [nbf.v4.new_code_cell("""
import altair as alt
alt.renderers.enable("notebook")
# ... load df
alt.Chart(df).mark_point().encode(x='x', y='y')
""")]
ep = ExecutePreprocessor(timeout=600, kernel_name='python3')
ep.preprocess(nb, {'metadata': {'path': '.'}})
html_exporter = HTMLExporter()
html_exporter.template_file = 'basic'
(body, resources) = html_exporter.from_notebook_node(nb)
with open('out.html', 'w') as f:
f.write(body)
流程运行得很好,它生成了一个笔记本和一个HTML文件,并且执行了所有代码。但是,代码单元格的输出如下所示(无图表):
<vega.vegalite.VegaLite at 0x7f80c4d8a090>
当我将笔记本写出为.ipynb文件并手动执行时,在相同的环境中,图表将按预期显示。可以这样使用牛郎星吗?我想知道我在Python会话中运行nbformat会不会有什么不同,也许它只能在浏览器中呈现图表?
发布于 2019-11-11 20:10:37
通过nbformat生成notebook和运行notebook live之间的区别在于,nbformat没有附加前端。这在这里很重要,因为对于Altair图表,前端notebook扩展是呈现图表的方式。
那么,当您在生成notebook后打开它时,为什么呈现的图表没有显示出来呢?这是因为Jupyter notebook的安全模型:当打开一个新的不可信的notebook时,notebook不会执行现有的Javascript,因为这将是一个简单的攻击路径(例如,攻击者可以使用javascript发布一个notebook,在加载时执行python代码,在您有机会阅读notebook内容之前,执行python代码来搜索硬盘中的敏感信息并将其发送给攻击者)。
因此,在呈现图表时,vega notebook扩展会生成一个PNG预览并将其保存到notebook,因此当您与其他人共享它时,他们会得到一个静态图表预览作为占位符,直到他们实际执行notebook为止。但是,如果您在没有前端的情况下执行notebook,则不会生成此PNG预览,因此在打开notebook时什么也看不到。
解决这个问题的最好方法是使用JupyterLab而不是Juptyer Notebook。在JupyterLab中,牛郎星图表是使用VegaLite解释的VegaLite模拟类型保存的,并转换为图表。这不涉及从notebook执行任意javascript,因此您以这种方式创建的图表将在JupyterLab加载时呈现在notebook中。因为classic不支持基于mimebundle的渲染,所以在classic notebook中不使用此路径。
如果您必须使用Jupyter Notebook而不是JupterLab,那么除了使用诸如selenium之类的无头浏览器引擎以编程方式执行您的notebook以及将呈现JupterLab预览的浏览器前端之外,没有任何方法可以解决这个问题。
https://stackoverflow.com/questions/58807145
复制