1

在本地运行$ipython3 notebook --pylab=inline,我使用 pylab 和 python 3.3 保存了一个带有小 png 图的简单笔记本。

笔记本单元格的内容:

from pylab import *

x = linspace(0, 5, 10)
y = x ** 2
figure()
plot(x, y, 'r')
xlabel('x')
ylabel('y')
title('title')
show()

运行单元格会导致显示内联 png 图形。保存的文件 (my_notebook.ipynb) 有一个保存为数据 uri 的 .png:

{ ..., "png":"iVBO...ZUmwK\n...", ... }

执行命令后:

ipython3 nbconvert --to html my_notebook.html

my_notebook.html 是用图形作为数据 uri 生成的,如下所示:

<img src="data:image/png;base64,b'iVBO...ZUmwk\n..." >

在最新的 chrome 或 firefox 中,在本地打开 file:///.../my_notebook.html 时,图像数据 uri 不加载/显示,并且 chrome 控制台报告 img 标签的“加载资源失败”。

加载图像然后使用 imshow() 显示时,我得到了相同的结果。这些数字在笔记本上看起来很好。在 nbconvert 到 html 之后,它们不显示(根本)。

(注意图像数据 uri 中的转义换行符 - 我尝试用实际换行符替换数据字符串中的所有转义换行符,结果没有变化)

如何在浏览器中本地打开的 ipython 笔记本(“file:///.../my_notebook.html”)的 nbconverted-html 版本中显示 png 图形?

(我宁愿不必保存每个图并手动修改转换后的 html 以引用磁盘上保存的图。)

编辑: 版本:

python 3.3.1
ipython==1.0.0
matplotlib==1.2.1
Pillow==2.1.0 (PIL)
4

1 回答 1

0

首先安装BeautifulSoup4

pip install BeautifulSoup4

然后使用以下函数冻结您生成的 html 文件。图像将放置在images与 html 文件相同的目录下的文件夹中。

import os
import re
import base64
from bs4 import BeautifulSoup as BS
from uuid import uuid4


def dump(path, data):
    root = os.path.dirname(path)
    if not os.path.exists(root):
        os.makedirs(root)
    with open(path, 'wb') as f:
        f.write(data)
    # for windows
    return path.replace('\\', '/')


def freeze_html(path):
    '''pass in absolute path of your html'''
    root = os.path.dirname(path)
    with open(path, 'rb') as f:
        soup = BS(f.read())
    for img in soup.find_all('img'):
        m = re.search(r"data:image/png;base64,b'(.*)'", img['src'])
        if m:
            iname = uuid4()
            ipath = os.path.join(root, 'images', '%s.png' % iname)
            # remove '\n'
            s = m.group(1).replace(r'\n', '')
            img['src'] = os.path.relpath(
                dump(ipath, base64.b64decode(s.encode('ascii'))),
                root
            )
    with open(path, 'wb') as f:
        f.write(soup.encode('utf-8'))

如果您不需要进一步将其转换为 tex 或 pdf,您可以将字符串(\n已删除)写回img['src'](带data:image/png;base64,前缀):

import re
from bs4 import BeautifulSoup as BS


def freeze_html(path):
    '''pass in absolute path of your html'''
    with open(path, 'rb') as f:
        soup = BS(f.read())
    for img in soup.find_all('img'):
        m = re.search(r"data:image/png;base64,b'(.*)'", img['src'])
        if m:
            # remove '\n'
            s = m.group(1).replace(r'\n', '')
            img['src'] = 'data:image/png;base64,' + s
    with open(path, 'wb') as f:
        f.write(soup.encode('utf-8'))

我更喜欢将 png 保存到单独的文件,因为它对 xelatex 更友好。

于 2013-09-12T02:12:59.300 回答