使用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()
简单地使用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)
当然我们可以尝试清空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)
优雅方法
最优雅的方式是使用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)
同时实现了图像持续更新和文字正常输出。