使用nbformat生成Jupyter笔记本-Altair图表不显示

时间:2019-11-11 18:58:21

标签: jupyter-notebook jupyter altair

我正在尝试以编程方式生成一个笔记本,执行它,并使用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文件写出并手动执行时,在相同的环境中,图表将按预期显示。是否可以通过这种方式使用Altair?我想知道我在Python会话中运行nbformat的事实是否有所不同,也许它只能在浏览器中呈现图表?

1 个答案:

答案 0 :(得分:1)

通过nbformat生成笔记本和实时运行笔记本之间的区别在于nbformat没有附加前端。这一点很重要,因为对于Altair图表,前端笔记本扩展是呈现图表的原因。

那么,生成笔记本后打开笔记本时为什么不显示渲染的图表?这是因为Jupyter笔记本电脑的安全模型:打开新的不受信任的笔记本电脑时,笔记本电脑将不执行现有的Javascript,因为这是一条简单的攻击路径(例如,攻击者可以发布带有javascript的笔记本电脑,并在加载时执行python在您有机会阅读笔记本内容之前,在硬盘上搜索敏感信息并将其邮寄给攻击者的代码。

因此,在绘制图表时,vega Notebook扩展会生成一个PNG预览并将其保存到笔记本中,因此当您与他人共享时,他们会获得静态图表预览作为占位符,直到他们实际执行该笔记本。 但是,如果您在没有前端的情况下执行笔记本,则不会生成此PNG预览,因此打开笔记本时您什么也看不到。

解决此问题的最佳方法是使用JupyterLab而不是Juptyer Notebook。在JupyterLab中,使用VegaLite Mimetype保存Altair图表,该类型由vega labextension解释并变成图表。这不涉及从笔记本执行任意javascript,因此您在JupyterLab加载时会以这种方式创建的图表在笔记本中呈现。经典笔记本电脑不使用此路径,因为经典笔记本电脑不支持基于mimebundle的渲染。

如果必须使用Jupyter Notebook而不是JupterLab,除了可能使用selenium之类的无头浏览器引擎以可渲染的浏览器前端以编程方式执行笔记本之外,实际上没有任何解决方法PNG预览。