jupyte中动态更新matplotlib的曲线

使用python进行数值实验的时候,我们常常会在程序运行结束之后利用matplotlib绘制出结果的曲线。问题是,当程序需要运行很长世间的时候,我们不能立即查看出图的效果。

错误做法

如果简单地多次调用plot,几次绘制的曲线会堆在一个图里:

for i in range(5):
    x = list(range(i, i+5))
    y = [xx**2 for xx in x]
    plt.plot(x, y)
    plt.show()

jupyte中动态更新matplotlib的曲线_第1张图片


简单地使用clf清除画布,中间sleep的时候是没有图像输出的,只能看到最后的输出

for i in range(5):
    x = list(range(i, i+5))
    y = [xx**2 for xx in x]

	# 清空figure
    plt.clf()
    plt.plot(x, y)
    plt.show()
    time.sleep(1)

jupyte中动态更新matplotlib的曲线_第2张图片


当然我们可以尝试清空display的内容,这样子图片确实可以更新,但是运行过程中打印的值全部都会丢失。(如下图中只剩下最后的i=4

import IPython
for i in range(5):
    x = list(range(i, i+5))
    y = [xx**2 for xx in x]
    
    # 清空display
    IPython.display.display(plt.gcf())
    IPython.display.clear_output(wait=True)
    
    plt.plot(x, y)
    plt.show()
    print('i={}'.format(i))
    time.sleep(1)

jupyte中动态更新matplotlib的曲线_第3张图片

优雅方法

最优雅的方式是使用matplotlib中axis的set_data方法,实时更新曲线。

#打开matplotlib的交互显示模式
%matplotlib notebook

plt.figure()
#绘制一条空曲线,令下面ax.lines里不为空
plt.plot([], [])

#获取当前figure和axis
fig = plt.gcf()
ax = plt.gca()

for i in range(5):
    x = list(range(i, i+5))
    y = [xx**2 for xx in x]
    
    # 更新数据
    ax.lines[0].set_data(x, y)

	#重置已有曲线的的坐标轴时,要先解除限制(见ax.autoscale_view的官方文档)
    ax.relim()
    #重设坐标轴,让图像更协调
    ax.autoscale_view()
    
    # 显示图片
    fig.canvas.draw()
    
    # 正常打印
    print(i)
    time.sleep(1)

jupyte中动态更新matplotlib的曲线_第4张图片

同时实现了图像持续更新和文字正常输出。

你可能感兴趣的:(python)