lee-romantic 's Blog
Everything is OK!
Toggle navigation
lee-romantic 's Blog
主页
About Me
归档
标签
matplotlib的阻塞和交互及动态画图
2018-10-08 20:47:30
699
0
0
lee-romantic
##一.介绍 在使用`matplotlib`的过程中,发现不能像matlab一样同时开几个窗口进行比较,于是查询得知了交互模式,但是放在脚本里运行的适合却总是一闪而过,图像并不停留,遂仔细阅读和理解了一下文档,记下解决办法,问题比较简单,仅供菜鸟参考。 python可视化库matplotlib有两种显示模式: ×**阻塞(block)模式** ×**交互(interactive)模式** `在Python Consol命令行中,默认是交互模式。而在python脚本中,matplotlib默认是阻塞模式`。 jupyter notebook中,默认是交互模式的(因此去掉plt.ion(),plt.ioff(),plt.show(),都不会影响原来的效果),而且貌似不能改为阻塞模式????,但是显示图像并不会开一个窗口,而是会一张一张的全部显示在网页上,所以即使是“一闪而过”,也看不出来。想要实时动态的显示,参看其他笔记“jupyter notebook matplotlib画图动态刷新” ##二.阻塞与交互的区别 `在交互模式下`: plt.plot(x)或plt.imshow(x)是直接出图像,不需要plt.show() ``貌似还是需要,否则一闪而过`` 如果在脚本中使用ion()命令开启了交互模式,没有使用ioff()关闭的话,则图像会一闪而过,并不会常留。要想防止这种情况,需要在plt.show()之前加上ioff()命令。``这倒是对的`` `在阻塞模式下`: 打开一个窗口以后必须关掉才能打开下一个新的窗口。这种情况下,默认是不能像Matlab一样同时开很多窗口进行对比的。``这也是对的`` plt.plot(x)或plt.imshow(x)是不直接出图像,需要plt.show()后才能显示图像 ##三.一个简单的示例 下面这个例子讲的是如何像matlab一样同时打开多个窗口显示图片或线条进行比较,同时也是在脚本中开启交互模式后图像一闪而过的解决办法: ``` import matplotlib.pyplot as plt plt.ion() # 打开交互模式,实际上交互模式在只打开一个figure窗口的情况下,与阻塞模式没啥区别 # 同时打开两个窗口显示图片 plt.figure() plt.imshow(i1) plt.figure() plt.imshow(i2) # 显示前关掉交互模式 plt.ioff() plt.show() ``` ##四.在pycharm中的问题 不知道为什么,在pycharm中好像始终是阻塞模式,即使使用了plt.ion()和plt.ioff(),好像也没什么用,使用交互模式时,还是只会生成很多张静态图片 ,而不是动态图??????就像阻塞模式一样??? **原因**: 参考:http://mamicode.com/info-detail-2512952.html 首先,使用了plt.ion()和plt.ioff(),肯定是开启/关闭了交互模式的.这里生成很多张静态图片,并不是阻塞模式或者交互模式所能决定的. 阻塞和交互,主要影响的是窗口figure; 在pycharm中,`file->setting->tools-> Python scientific`,我们默认的是勾选了`show plots in tool window`,正是这个设置,导致了我们无法在同一张图上面再画图,而是每次都会重新产生一张图片,产生很多张静态图.去掉钩后,plots则会单独显示,每个figure一个窗口.此时,不论是在交互模式还是阻塞模式下,`都可以在一张图上展示动态图了.` 因为阻塞和交互,主要是针对figure的,因此对单一的figure,分几个子区域,每次用cla()擦除,再plot,imshow就行了 ##五.展示动态图 `展示动态图,既可以像上一个问题中提到的那样,在同一张图figure上不断擦除,再画,再擦除...,也可以建很多个figure,来实现动态效果.` **(1)问题** 有时候我们,需要的不只是一个动态展示的效果,`还需要中间的每一张图`. 如果我们不勾选`show plots in tool window,`且让程序不在一张图上画图而是生成很多个figure,则会产生很多张图覆盖在屏幕上.这样的图可能不好保存.这时就需要勾选`show plots in tool window`了. 假设我们仍然要在勾选`show plots in tool window`的情况下,展示多个图,如果不通过隐式的方式画图,则需要每次自己新建子图,才能够同时展示多个图. 这种情况下,建议使用隐式方式.比如我每次需要两个图进行对比,需要同时产生很多张图: ``` #train_dataset为minist的data数据 for i in range(6): plt.subplot(121) plt.imshow(train_dataset.train_data[i], cmap='Blues') plt.subplot(122) plt.imshow(train_dataset.train_data[i+1], cmap='Accent') #plt.pause(0.1) #如果没有勾选show plots in tool window,则图片不会一张一张的显示,则需要暂停pause才能看到效果,当然,有pause则不需要show了 plt.show() #该代码片段,在阻塞模式下,则需要一张一张的关闭窗口;在交互模式下,有pause,则会动态显示. ``` 而不能通过如下方式: ``` #show some train data fig = plt.figure(figsize=(8,6)) ax1=fig.add_subplot(2,2,1) ax2=fig.add_subplot(2,2,2) plt.ion()#交互模式在只打开一个figure窗口的情况下,与阻塞模式没啥区别,这里可有可无 for _ in range(5): ax2.cla() ax1.cla() ax2.imshow(train_dataset.train_data[_], cmap='Blues') ax1.imshow(train_dataset.train_data[_+1], cmap='Accent') plt.pause(0.2) plt.ioff() plt.show() ``` 后面这种方式,是先定义一个画布,然后划分成两个子区域,尝试每次在两个子区域上画图,并且暂停,擦除,重新画图......嗯,想法很好,但是在这里行不通(取消勾选`show plots in tool window`则行得通); **(2)原因**:无论是否处于阻塞模式,只要勾选了`show plots in tool window`的,所以每次show()(`plt.pause()也会自动show的,`)了之后,就暂停了(每次都以静态图方式显示,无法再对cla()擦除,为什么呢???),这样的结果就是,上面的for循环,最后只会有一张图显示. 因此,解决办法就是只有不在原图上改,而是每次新产生figure了.``可以隐式的产生新的画布,或者每次自己定义子图,比如:`` ``` for i, locator in enumerate(locators): plt.subplot(n_locators, 1, i + 1) #或者fig.add_subplot(n_locators, 1, i + 1)) #或者直接plot也行,没有子图时,系统会自动不停的创建 plt.plot(....) #其他操作 plt.show() ``` **(3)总结**:pycharm中,无论阻塞模式还是交互模式, a)勾选了`show plots in tool window`,则不可能看到真正意义上的动态图,只能是一张一张的图,产生`动态效果的图`的方式就最好是每次都重新生成figure图,来得到多张静态图拼成动态图; b)未勾选时,则既可以在原来的figure图上擦除,再画,再擦除...也可以每次都重新生成图来达到动态效果!
上一篇:
torch学习笔记1
下一篇:
jupyter notebook matplotlib画图动态刷新
0
赞
699 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册