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来渲染。其实还有 Qt4AggGTKAggTkAgg等很多可以使用。这是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中的设置。

  1. matplotlibrc文件中的backend参数,也就是我们上面说的方案一:

(如果想定制化matplotlib其他的参数,点击查看):

backend : TkAgg   # Agg(antigrain) 渲染到 Tk canvas (需要安装TkInter)
  1. 为当前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中,因为它会让我们很难发现问题。

  1. 要为单个脚本设置backend,也可以使用 -d 命令行参数:
> python script.py -dbackend

不推荐使用此方法,因为-d参数可能与解析命令行参数的脚本冲突(参考issue#1986)。

  1. 如果你的脚本依赖于特定的后端,则可以使用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渲染器的列表(每个渲染器都有一个同名支持,能够写入文件):

Renderer Filetypes Description
AGG png raster graphics – high quality images using the Anti-Grain Geometry engine
PS ps eps vector graphicsPostscript output
PDF pdf vector graphicsPortable Document Format
SVG svg vector graphicsScalable Vector Graphics
Cairo png ps pdf svg ... vector graphicsCairo graphics
GDK png jpg tiff ... raster graphics – the Gimp Drawing Kit Deprecated in 2.0

参考链接

  • 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 ---

交流

随意打赏☕️

取消

感谢你的慷慨!

扫码支持
希望本站内容对你有帮助

打开 支付宝 扫一扫

Scroll to top