升级Matplotlib至2.2.0后动画多帧渲染冻结问题求助
我之前也踩过类似的版本兼容坑,尤其是Enthought Canopy这种封装过的环境,和Matplotlib特定版本搭配时很容易出现线程管理类的问题,结合你描述的现象(冻结、PyEval_RestoreThread致命错误),给你几个针对性的解决方案:
1. 快速回退到兼容版本
既然你说代码在其他Matplotlib版本下正常运行,最直接的办法就是回退到之前能工作的版本,避开2.2.0里的bug。在Canopy的命令行中执行:conda install matplotlib=2.1.2
如果你的环境允许用pip,也可以用:pip install matplotlib==2.1.2
2.1.2是2.2.0之前的稳定版,和Canopy的环境适配性经过验证,能直接解决线程相关的保存冻结问题。
2. 强制指定动画保存后端
Matplotlib 2.2.0对动画保存后端的逻辑做了调整,在Canopy环境下可能默认后端不兼容。你可以修改保存代码,强制指定可靠的后端:
比如原来的保存代码:
ani.save('my_animation.mp4')
改成:
# 使用ffmpeg后端保存MP4 ani.save('my_animation.mp4', writer='ffmpeg') # 或者用pillow保存GIF格式 ani.save('my_animation.gif', writer='pillow')
记得先安装对应依赖:Canopy里安装ffmpeg用conda install ffmpeg,pillow一般默认自带,缺失的话用conda install pillow即可。
3. 切换到非交互式后端
Canopy的交互式后端(比如tkagg、qt5agg)可能和Matplotlib 2.2.0的动画保存线程产生冲突。你可以在代码开头添加以下代码,强制使用非交互式后端:
import matplotlib matplotlib.use('Agg') # 仅用于批量生成/保存图形,无实时预览
这样能彻底避免交互式界面的线程干扰,专注于动画保存。缺点是看不到实时动画预览,但能解决冻结问题。
4. 排查环境依赖冲突
Canopy自带的部分包可能和Matplotlib 2.2.0存在版本冲突,比如numpy、PyQt等。你可以用conda list查看当前环境的包版本,重点关注:
- numpy:Matplotlib 2.2.0要求numpy≥1.11,推荐1.15.4版本
- PyQt:推荐5.9.2版本,和2.2.0兼容性较好
执行以下命令更新到兼容版本:conda install numpy=1.15.4 pyqt=5.9.2
如果以上方法都无效,建议在Canopy中新建一个干净的虚拟环境,只安装Python、Matplotlib、numpy、ffmpeg等必要依赖,再测试代码,排除原有环境的依赖污染问题。
内容的提问来源于stack exchange,提问作者Oliver von Baron

