结合 Jupyter rich display 和 matplotlib 图表
Combining Jupyter rich display and matplotlib charts
我想要一段代码(一个分析模型)来生成一系列的 Jupter 输出,这样当模块在 Jupyter Notebook 中 运行 时,它会向笔记本输出一些 tables, HTML 按特定顺序输出和 matplotlib 图表。
这个想法是模型存储一个对象列表,我们稍后可以遍历它,显示每个对象。
我已经成功地使用 tables 和 HTML 使用如下代码:
from IPython.display import display
from IPython.display import HTML, Image
a = df.head(1)
b = HTML("<p>Hello</p>")
c = df.head(2)
display(a)
display(b)
display(c)
#A more general case would be:
for i in [a,b,c]:
display(i)
但是,我无法使 matplotlib 图表(例如使用 df.plot()
)以正确的顺序出现。调用 plt.show()
使我能够以正确的顺序输出单个图表,但如果有多个图表似乎对我没有帮助。
我设法实现的解决方法是将 matplotlib 图表输出到 .png,然后使用 Image 显示这些 png 图像。但是,如果可以的话,我宁愿避免将大量 .png 图表输出到文件中。
所有这一切背后的想法是,它允许我用 Python 编写的分析模型输出一种 'rich' 版本的日志记录,您可以在其中 'log' a table 或图表。
我在一定程度上解决了这个问题
下面是链接的相同内容。
它应该提供一些指导。
要点是:
- 将 png 数据打印到
StringIO
对象。 fig.canvas.pring_png(sio)
- 将其从二进制转换为 ascii。
binascii.b2a_base64(sio.getvalue())
- 将其插入 img 标签。
'<img src="data:image/png;base64,{} ">'.format(img_data)
例子
from IPython.core.display import HTML
import binascii
from StringIO import StringIO
import matplotlib.pyplot as plt
# open IO object
sio = StringIO()
# generate random DataFrame
np.random.seed(314)
df = pd.DataFrame(np.random.randn(1000, 2), columns=['x', 'y'])
# initialize figure and axis
fig, ax = plt.subplots(1, 1)
# plot DataFrame
ax.scatter(df.iloc[:, 0], df.iloc[:, 1]);
# print raw canvas data to IO object
fig.canvas.print_png(sio)
# convert raw binary data to base64
# I use this to embed in an img tag
img_data = binascii.b2a_base64(sio.getvalue())
# keep img tag outter html in its own variable
img_html = '<img src="data:image/png;base64,{} ">'.format(img_data)
HTML("<h1>Hello</h1><hr/>"+img_html)
我最终得到:
你也可以这样做:
df = pd.DataFrame({'a':[1,2,3],'b':[3,2,1]})
plt.interactive(False) # This will prevent matplotlib from showing the plots immediately
# You would want to create placeholders for different figures to show:
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
# Then place your plots on the relevant placeholders:
df.a.plot(ax=ax1)
df.b.plot(ax=ax2)
添加您的原始代码:
a = df.head(1)
b = HTML("<p>Hello</p>")
c = df.head(2)
for i in [a,b,fig1,c,fig2]:
display(i)
这使得表格、文本、数字的顺序符合要求:
我想要一段代码(一个分析模型)来生成一系列的 Jupter 输出,这样当模块在 Jupyter Notebook 中 运行 时,它会向笔记本输出一些 tables, HTML 按特定顺序输出和 matplotlib 图表。
这个想法是模型存储一个对象列表,我们稍后可以遍历它,显示每个对象。
我已经成功地使用 tables 和 HTML 使用如下代码:
from IPython.display import display
from IPython.display import HTML, Image
a = df.head(1)
b = HTML("<p>Hello</p>")
c = df.head(2)
display(a)
display(b)
display(c)
#A more general case would be:
for i in [a,b,c]:
display(i)
但是,我无法使 matplotlib 图表(例如使用 df.plot()
)以正确的顺序出现。调用 plt.show()
使我能够以正确的顺序输出单个图表,但如果有多个图表似乎对我没有帮助。
我设法实现的解决方法是将 matplotlib 图表输出到 .png,然后使用 Image 显示这些 png 图像。但是,如果可以的话,我宁愿避免将大量 .png 图表输出到文件中。
所有这一切背后的想法是,它允许我用 Python 编写的分析模型输出一种 'rich' 版本的日志记录,您可以在其中 'log' a table 或图表。
我在一定程度上解决了这个问题
下面是链接的相同内容。
它应该提供一些指导。
要点是:
- 将 png 数据打印到
StringIO
对象。fig.canvas.pring_png(sio)
- 将其从二进制转换为 ascii。
binascii.b2a_base64(sio.getvalue())
- 将其插入 img 标签。
'<img src="data:image/png;base64,{} ">'.format(img_data)
例子
from IPython.core.display import HTML
import binascii
from StringIO import StringIO
import matplotlib.pyplot as plt
# open IO object
sio = StringIO()
# generate random DataFrame
np.random.seed(314)
df = pd.DataFrame(np.random.randn(1000, 2), columns=['x', 'y'])
# initialize figure and axis
fig, ax = plt.subplots(1, 1)
# plot DataFrame
ax.scatter(df.iloc[:, 0], df.iloc[:, 1]);
# print raw canvas data to IO object
fig.canvas.print_png(sio)
# convert raw binary data to base64
# I use this to embed in an img tag
img_data = binascii.b2a_base64(sio.getvalue())
# keep img tag outter html in its own variable
img_html = '<img src="data:image/png;base64,{} ">'.format(img_data)
HTML("<h1>Hello</h1><hr/>"+img_html)
我最终得到:
你也可以这样做:
df = pd.DataFrame({'a':[1,2,3],'b':[3,2,1]})
plt.interactive(False) # This will prevent matplotlib from showing the plots immediately
# You would want to create placeholders for different figures to show:
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
# Then place your plots on the relevant placeholders:
df.a.plot(ax=ax1)
df.b.plot(ax=ax2)
添加您的原始代码:
a = df.head(1)
b = HTML("<p>Hello</p>")
c = df.head(2)
for i in [a,b,fig1,c,fig2]:
display(i)
这使得表格、文本、数字的顺序符合要求: