[英]Combining Jupyter rich display and matplotlib charts
I would like a piece of code (an analytical model) to produce a series out Jupter outputs so that when the module is run within Jupyter Notebook, it outputs to the notebook a number of tables, HTML outputs and matplotlib charts, in a specific order. 我想要一段代码(一个分析模型)来产生一系列Jupter输出,以便当模块在Jupyter Notebook中运行时,它以特定顺序向笔记本输出多个表,HTML输出和matplotlib图表。
The idea is that the model stores an list of objects, which we can later loop through, displaying each one. 这个想法是模型存储了一个对象列表,稍后我们可以循环显示每个对象。
I have managed to make this work with tables and HTML with code like as follows: 我设法使表和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)
However, I am unable to make matplotlib charts (eg using df.plot()
) appear in the correct order. 但是,我无法使matplotlib图表(例如,使用
df.plot()
)以正确的顺序显示。 Calling plt.show()
enables me to output a single chart in the right order, but doesn't seem to help me if there are multiple charts. 调用
plt.show()
使我能够以正确的顺序输出单个图表,但是如果有多个图表,似乎没有帮助。
I workaround I've managed to implement is outputting the matplotlib charts to .png and then using Image to display these png images. 我设法实现的解决方法是将matplotlib图表输出为.png,然后使用Image显示这些png图像。 However, I'd rather avoid having to output loads of .png charts to files if I can help it.
但是,如果可以的话,我宁愿避免将.png图表的负载输出到文件中。
The idea behind all of this is that it allows my analytical model written in Python to output a kind of 'rich' version of logging, where you can 'log' a table or a chart. 所有这些背后的想法是,它允许我使用Python编写的分析模型输出一种“丰富的”日志记录版本,您可以在其中“记录”表或图表。
You could also do something like this: 您还可以执行以下操作:
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)
Adding you original code: 为您添加原始代码:
a = df.head(1)
b = HTML("<p>Hello</p>")
c = df.head(2)
for i in [a,b,fig1,c,fig2]:
display(i)
And this makes the desired order of tables, text, figures: 这将使表,文本和图形按所需顺序排列:
I solved this problem to some extent HERE 我解决了这个问题,在一定程度上HERE
Below is the same content of the answer linked. 以下是链接的答案的相同内容。
It should provide some guidance. 它应该提供一些指导。
The essential points are: 要点是:
StringIO
object. StringIO
对象。 fig.canvas.pring_png(sio)
binascii.b2a_base64(sio.getvalue())
'<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)
I end up with: 我最终得到:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.