结合 Jupyter 丰富的显示和 matplotlib 图表

Posted

技术标签:

【中文标题】结合 Jupyter 丰富的显示和 matplotlib 图表【英文标题】:Combining Jupyter rich display and matplotlib charts 【发布时间】:2016-09-20 16:22:06 【问题描述】:

我想要一段代码(一个分析模型)来产生一系列 Jupter 输出,这样当模块在 Jupyter Notebook 中运行时,它会向笔记本输出一些表格、html 输出和 matplotlib 图表,在一个特定的顺序。

这个想法是模型存储一个对象列表,我们以后可以循环显示每个对象。

我已经设法通过如下代码使用表格和 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 编写的分析模型输出一种“丰富”版本的日志记录,您可以在其中“记录”表格或图表。

【问题讨论】:

【参考方案1】:

你也可以这样做:

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)

这使得表格、文本、图形的顺序符合要求:

【讨论】:

【参考方案2】:

我在一定程度上解决了这个问题HERE

下面是链接答案的相同内容。

它应该提供一些指导。

要点是:

    将 png 数据打印到 StringIO 对象。 fig.canvas.pring_png(sio) 将此从二进制转换为ASCII。 binascii.b2a_base64(sio.getvalue()) 将此插入到 img 标签中。 '&lt;img src="data:image/png;base64,&amp;#10;"&gt;'.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,&#10;">'.format(img_data)

HTML("<h1>Hello</h1><hr/>"+img_html)

我最终得到:

【讨论】:

谢谢。这种解决方案确实发生在我身上,但我不确定如何实施,所以这真的很有用。我会等着看是否有人提出更“本土”的答案,如果没有,我会接受这个

以上是关于结合 Jupyter 丰富的显示和 matplotlib 图表的主要内容,如果未能解决你的问题,请参考以下文章

Python Matplot中文显示完美解决方案

Python Matplot中文显示完美解决方案

matplot绘图

matplot:在matplotlib中显示标签的问题[重复]

Python Matplot中文显示完美解决方案

Python Matplot中文显示完美解决方案