如何让Jupyter Notebook中pandas DataFrame绘图按预期顺序显示?
问题
在VS Code的Jupyter扩展中,我给Notebook首行配置了%matplotlib widget,通过循环动态生成分组标题和对应DataFrame的绘图,核心代码如下:
%matplotlib widget import pandas from IPython.display import display_markdown dictionary: dict[str, pandas.DataFrame] = { "DataFrame 1": pandas.util.testing.makeDataFrame(), "DataFrame 2": pandas.util.testing.makeDataFrame(), } group: str dataframe: pandas.DataFrame for group, dataframe in dictionary.items(): display_markdown("## %s" % (group), raw=True) dataframe.plot()
运行后所有分组标题会先全部显示,之后才显示所有绘图,无法实现标题-绘图的顺序展示效果,该如何解决?
解决方案
出现该问题是因为matplotlib widget的绘图渲染与display_markdown的输出存在异步队列差异,导致绘图被延迟批量渲染。可通过以下两种方法解决:
方法1:显式使用display()输出绘图对象
修改循环内代码,将dataframe.plot()返回的绘图对象通过IPython.display.display()显式输出,确保标题与绘图同步渲染:
%matplotlib widget import pandas from IPython.display import display_markdown, display dictionary: dict[str, pandas.DataFrame] = { "DataFrame 1": pandas.util.testing.makeDataFrame(), "DataFrame 2": pandas.util.testing.makeDataFrame(), } for group, dataframe in dictionary.items(): display_markdown(f"## {group}", raw=True) ax = dataframe.plot() display(ax.figure)
方法2:切换为%matplotlib inline(无需交互绘图时)
如果不需要widget的交互功能,将首行魔法命令改为%matplotlib inline,默认会按代码执行顺序同步输出标题和绘图:
%matplotlib inline import pandas from IPython.display import display_markdown dictionary: dict[str, pandas.DataFrame] = { "DataFrame 1": pandas.util.testing.makeDataFrame(), "DataFrame 2": pandas.util.testing.makeDataFrame(), } for group, dataframe in dictionary.items(): display_markdown(f"## {group}", raw=True) dataframe.plot()
VS Code额外注意事项
- 确保VS Code的Jupyter扩展为最新版本,旧版本可能存在渲染队列bug;
- 使用
%matplotlib widget时,若后续绘图复用旧画布,可导入matplotlib.pyplot并在每次绘图后添加plt.close()处理(配合display()使用时通常无需额外操作)。
内容的提问来源于stack exchange,提问作者Torsten Knodt
相关产品推荐
相关产品推荐

