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

标签 python 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 session 中运行 nbformat 是否会产生影响,也许它只能在浏览器中呈现图表?

最佳答案

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

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

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

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

如果您必须使用 Jupyter Notebook 而不是 JupterLab,除了使用 headless 浏览器引擎(例如 selenium)之外,实际上没有任何方法可以解决此问题。使用浏览器前端以编程方式执行笔记本,该前端将呈现 PNG 预览。

关于python - 使用 nbformat 生成 Jupyter 笔记本 - Altair 图表不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58807145/

相关文章:

python - Python 2 和 3 之间 ctypes 的差异

python - 如何使 matplotlibs nbagg 后端生成 SVG?

python - 尝试从 Jupyter Notebook 使用 Spark 访问 Google Cloud Bigtable 时出现区域错误

jupyter-notebook - ipython/jupyter 笔记本中的只读单元格

python - 有没有一种快速的方法可以将 pandas DataFrame 变成漂亮的 HTML 表格?

python - 在 Python 中访问稀疏矩阵中的单个条目

python - 在 python 中只能检索一次压缩值吗?

python - K-Means 按组分类

python - 阻止 Jupyter notebook 在每次 alt-enter(运行)后生成新的空白单元格

python - 如何将 CSV 文件读入 Jupyter Notebook