macOXS中使用matplotlib遇到的问题及探究
第一次在mac系统上使用matplotlib库的时候,在执行的时候,往往会遇到下面这样的问题:
ImportError: Python is not installed as a framework. balabala....
解决方案
当然这个问题很好解决,网上有一搜就会找到如下两种解决方案:
第一种方案是在系统中设置:
假设你已经通过pip install matplotlib安装了matplotlib,那么在你的根目录中会有一个名为〜/ .matplotlib的目录。
在这个目录中创建一个matplotlibrc的文件 ,在里面添加一行代码:backend: TkAgg,保存退出即可。
总结为一行shell命令就是:echo "backend: TkAgg" >> ~/.matplotlib/matplotlibrc
这种方式可以设定整个系统的matplotlib渲染使用的引擎,但是不好的是,代码会变得不可移植,如果服务器很多,我们需要每一台机器都去设置这个参数,这时候就需要使用第二种方案。
第二种方案是在代码中设置:
在引用matplotlib库的代码之前,添加如下两行代码(确认安装TkInter):
import matplotlib
matplotlib.use('TkAgg')
这样也可以临时的修改前面提到的 backend变量。
为什么要这样做?
从两种解决方法基本可以看出,两种方法都是通过修改一个叫做 backend的值来解决的。但这个TKAgg是什么鬼呢?
回答这个问题就需要知道为什么会默认的情况会产生上面的那个 ImportError。出现这个错误的原因是,在mac os系统镜像中渲染matplotlib的后端,默认情况下使用的是Cocoa的API来渲染。其实还有 Qt4Agg , GTKAgg , TkAgg等很多可以使用。这是macosx与其他windows或linux os相比不同的地方。
什么是backend?
网上有很多的文档或解决方案都会提到backend,但许多用户对此术语会感到困惑(比如我)。matplotlib会面对许多不同的用法和输出形式。比如,有人会在python shell交互使用matplotlib,并在键入命令时弹出绘图窗口。有人将matplotlib嵌入到图形用户界面(如wxpython或pygtk)中以构建丰富的应用程序。还有人在批处理脚本中使用matplotlib从一些数值模拟生成postscript图像,还有一些是在Web应用程序服务器中生成posts动画以提供动态图形。
为了支持所有这些用法,matplotlib可以提供不同的输出,这些输出中都称为backend; “frontend”是面向用户的代码,即绘图代码,而backend完成幕后的所有生成图形的复杂工作。
matplotlib中有两种类型的backend:
用户界面后端(用于pygtk,wxpython,tkinter,qt4或macosx等,也被称为“交互式后端”)
硬拷贝后端(用于制作图像文件PNG,SVG,PDF,PS等,也被称为“非交互式后端”)
设置backend的方法其实不止有网上提到两种方案,一共有四种方法。如果它们彼此有冲突,将使用以下列表中最后提到的方法,例如,调用use()则将会覆盖matplotlibrc中的设置。
matplotlibrc文件中的backend参数,也就是我们上面说的方案一:
(如果想定制化matplotlib其他的参数,点击查看):
backend : TkAgg # Agg(antigrain) 渲染到 Tk canvas (需要安装TkInter)
为当前shell或单个脚本设置MPLBACKEND环境变量:
> export MPLBACKEND="module://my_backend"
> python simple_plot.py
> MPLBACKEND="module://my_backend" python simple_plot.py
设置此环境变量将覆盖matplotlibrc中的backend参数值,即使当前工作目录中存在matplotlibrc也是如此。因此,不鼓励在全局设置MPLBACKEND,例如在.bashrc或.profile中,因为它会让我们很难发现问题。
要为单个脚本设置backend,也可以使用 -d 命令行参数:
> python script.py -dbackend
不推荐使用此方法,因为-d参数可能与解析命令行参数的脚本冲突(参考issue#1986)。
如果你的脚本依赖于特定的后端,则可以使用use()函数:
import matplotlib
matplotlib.use('PS') # 默认输出 postscript
如果要使用use()函数,则必须在导入matplotlib.pyplot之前调用。导入pyplot后调用use()将不起作用。如果想要使用不同的后端,则不得不对源码做编辑,修改use()中的代码来完成。因此,除非必要,否则应该避免显式调用use()。
backend名称规范不区分大小写;例如,'GTKAgg'和'gtkagg'是等价的。
backend选择列表
交互式列表
这些是支持的用户界面和渲染器组合,能够显示到屏幕并使用非交互式列表中的适当渲染器写入文件:
Backend
Description
GTKAgg
Agg rendering to a GTK 2.x canvas (requires PyGTK and pycairo or cairocffi; Python2 only)
GTK3Agg
Agg rendering to a GTK 3.x canvas (requires PyGObject and pycairo or cairocffi)
GTK
GDK rendering to a GTK 2.x canvas (not recommended and d eprecated in 2.0) (requires PyGTK and pycairo or cairocffi; Python2 only)
GTKCairo
Cairo rendering to a GTK 2.x canvas (requires PyGTK and pycairo or cairocffi; Python2 only)
GTK3Cairo
Cairo rendering to a GTK 3.x canvas (requires PyGObject and pycairo or cairocffi)
WXAgg
Agg rendering to to a wxWidgets canvas (requires wxPython)
WX
Native wxWidgets drawing to a wxWidgets Canvas (not recommended and deprecated in 2.0) (requires wxPython)
TkAgg
Agg rendering to a Tk canvas (requires TkInter)
Qt4Agg
Agg rendering to a Qt4 canvas (requires PyQt4 or pyside)
Qt5Agg
Agg rendering in a Qt5 canvas (requires PyQt5)
macosx
Cocoa rendering in OSX windows (presently lacks blocking show() behavior when matplotlib is in non-interactive mode)
非交互式列表
以下是matplotlib渲染器的列表(每个渲染器都有一个同名支持,能够写入文件):
参考链接
https://stackoverflow.com/questions/21784641/installation-issue-with-matplotlib-python
https://matplotlib.org/faq/usage_faq.html#what-is-a-backend
https://matplotlib.org/users/customizing.html#customizing-matplotlib
--- EOF ---