如何更改matplotlib后端

107
我正在遇到以下问题。我需要生成包含一系列图表的报告。除了一个图表外,所有这些图表都是使用Matplotlib的默认后端(TkAgg)制作的。其中一个图表需要使用Cairo后端制作,原因是我正在绘制一个igraph图,只能使用Cairo进行绘制。
问题在于我无法即时更改后端,例如以下代码不起作用: matplotlib.pyplot.switch_backend('cairo.png') (我知道switch_backend功能是实验性的)
我还尝试过matplotlib.use("cairo.png"),但这会导致导入问题,因为matplotlib.use("cairo.png")语句应该在导入matplotlib.pyplot之前执行。但是在脚本的生命周期中,我需要两个不同的后端。
所以我的问题是,有没有人有一个代码片段,展示如何在Matplotlib中切换后端?
非常感谢!
更新: 我编写了一个片段,加载matplotlib,显示默认后端,卸载matplotlib,重新加载并更改后端:
import matplotlib
import matplotlib.pyplot as plt
import sys
print matplotlib.pyplot.get_backend()

modules = []
for module in sys.modules:
    if module.startswith('matplotlib'):
        modules.append(module)

for module in modules:
    sys.modules.pop(module)

import matplotlib
matplotlib.use("cairo.png")
import matplotlib.pyplot as plt

print matplotlib.pyplot.get_backend()

但这真的是做事的方式吗?
更新2:昨天我有些严重的脑冻结...最简单和最明显的解决方案是对所有图表使用Cairo后端,而不切换后端 :)
更新3:实际上,这仍然是一个问题,所以任何知道如何动态切换matplotlib后端的人...请发表你的答案。

有一个 pyplot.switch_backends()。它可能在你的情况下无法正常工作。 - jfs
9个回答

81

六年后,我遇到了一个类似的问题,当我试图决定使用哪个后端时。
请注意查看下面的注意事项

这段代码片段对我很有效:

import matplotlib
gui_env = ['TKAgg','GTKAgg','Qt4Agg','WXAgg']
for gui in gui_env:
    try:
        print("testing", gui)
        matplotlib.use(gui,warn=False, force=True)
        from matplotlib import pyplot as plt
        break
    except:
        continue
print("Using:",matplotlib.get_backend())

Using: GTKAgg

根据您可以推断出,交换 backend 只需要在强制引入新的 backend 后重新导入 matplotlib.pyplot 就可以了。

matplotlib.use('WXAgg',warn=False, force=True)
from matplotlib import pyplot as plt
print("Switched to:",matplotlib.get_backend())

Switched to: WXAgg

如果仍然有困难,这段代码将会打印出以下内容:
非 Gui 后端列表;
Gui 后端列表;
然后尝试使用每个 Gui 后端来查看它是否存在并正常工作。

import matplotlib
gui_env = [i for i in matplotlib.rcsetup.interactive_bk]
non_gui_backends = matplotlib.rcsetup.non_interactive_bk
print ("Non Gui backends are:", non_gui_backends)
print ("Gui backends I will test for", gui_env)
for gui in gui_env:
    print ("testing", gui)
    try:
        matplotlib.use(gui,warn=False, force=True)
        from matplotlib import pyplot as plt
        print ("    ",gui, "Is Available")
        plt.plot([1.5,2.0,2.5])
        fig = plt.gcf()
        fig.suptitle(gui)
        plt.show()
        print ("Using ..... ",matplotlib.get_backend())
    except:
        print ("    ",gui, "Not found")

注意事项: 自 matplotlib 3.3.0 版本以来的更改

  • matplotlib.use 的第一个参数已从 arg 更名为 backend(仅适用于关键字传递)。
  • matplotlib.use 的 warn 参数已被删除。如果 force 已设置,则切换后端失败将始终引发 ImportError;必要时捕获该错误。
  • 除第一个参数外,matplotlib.use 的所有参数现在都是关键字参数。

谢谢!这很好地帮助我找到了适合这个例子的后端:https://dev59.com/2Gct5IYBdhLWcg3wuPq6 - James Nelson
Rolf of Saxony,LOL非常有帮助,我仍然收到来自将近十年前Ubuntu和Android帖子的回复。 - James Nelson
1
warn=False 参数已不再可用。 - not2qubit
@not2qubit 已经注意到了 - 谢谢。已添加警告。 - Rolf of Saxony
1
不得不说声谢谢。你为我省了大量的工作! - bob.sacamento
1
@bob.sacamento 太好了,那我的工作就完成了 ;) - Rolf of Saxony

40

有一个“实验性”的功能:

import matplotlib.pyplot as plt
plt.switch_backend('newbackend')

摘自Matplotlib文档.

将默认后端切换为新的后端。这个实验性的功能只能用于切换到一个图像后端。例如,如果您有一堆PostScript脚本想要从交互式IPython会话中运行,您可能需要在运行它们之前切换到PS后端,以避免弹出一堆GUI窗口。如果您试图从一个GUI后端交互地切换到另一个,程序将崩溃。调用此命令将关闭所有打开的窗口。


无法识别的后端字符串“newbackend”。我该怎么办? - TSR
7
@TSR 将 'newbackend' 替换为 GUI 后端,例如 'Qt4Agg'。 - YashTD

16

为什么不直接使用内置的reload函数 (importlib.reload在Python 3中)?

import matplotlib
matplotlib.use('agg')

matplotlib = reload(matplotlib)
matplotlib.use('cairo.png')

你的意思是不能重新加载matplotlib和matplotlib.pyplot吗?还是你只是在说我的代码片段不完整? - fredbaba
嗯,可能是IPython的一个小问题。在常规控制台中似乎运行良好。 - Mad Physicist
1
我认为这是一个例子,证明它不起作用:“python -c"import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"。是这样吗? - Lukas

8

我不确定这是否是你要找的内容。

你可以通过matplotlibrc文件更改你的后端,该文件包含了matplotlib的某些配置。

在你的脚本中,你可以输入:

matplotlib.rcParams['backend'] = 'TkAgg' 

或者类似的东西,用于在后端之间切换。


2
实际上,您可以在rcParams字典中指定后端,但这并不能解决从一个后端切换到另一个后端的问题。 - DrDee
您可以在配置文件中设置默认后端,该文件将被Matplotlib自动识别:~/.config/matplotlib/matplotlibrc - scrutari

7

附加信息

虽然每个人都有自己喜欢的后端,但是要想知道需要安装什么和需求是什么,还是相当混乱的。至少在试图理解晦涩难懂的文档时如此。今天我进行了几次实验,并认为我已经找到了每个后端最简单的解决方案,以便在Windows下使用Py3.8.5(不带内置Qt)绘制matplotlib图表。以下是我的研究结果:

#--------------------------------------
# Installing the matplotlib backends
#--------------------------------------
# https://matplotlib.org/users/installing.html

pip install pycairo                     # [1] Cairo :   GTK3 based backend (replaces: cairocffi)    [1.2 Mb]
#pip install mplcairo                   # [1] Cairo :   Easy & Specific for matplotlib              [1.7 Mb]
#pip install PyQt5                      # [2] Qt5   :   Require: Qt's qmake tool                    []
pip install PySide2                     # [3] Qt5   :   Require: shiboken2 & Clang lib bindings     [136 Mb]
pip install wxPython                    # [4] WxAgg :   ??                                          [18.1 Mb]
pip install tornado                     # [5] WebAgg:   Require: pycurl,twisted,pycares ??          [422 kb]

以下是所有PyPi或Repositories的链接:
[1] https://pypi.org/project/pycairo/       # Requires GTK3+: https://www.gtk.org/
[1] https://pypi.org/project/mplcairo/      # https://github.com/matplotlib/mplcairo
[2] https://pypi.org/project/PyQt5/         # 
[3] https://pypi.org/project/PySide2/       # 
[4] https://pypi.org/project/wxPython/      # https://github.com/wxWidgets/Phoenix/
[4] https://github.com/wxWidgets/wxWidgets/releases
[5] https://pypi.org/project/tornado/       # https://github.com/tornadoweb/tornado

可是,令人惊讶的是,尽管有大量关于如何使用 Tcl/Tktkinter 包的文档,但我无法安装它,也找不到任何有用的指导说明如何将 DLL 文件导入 Python。对于 Linux,这很简单,只需使用操作系统包管理器 apt-get install <tk-what-not> 即可,但是在 Windows 上没有此选项,也没有任何类似的简单方法。这里是你可以获得的许多不同二进制文件的列表。

[6] http://www.bawt.tcl3d.org/download.html                 # Use Tcl-Pure (no additional packages)
[6] https://www.magicsplat.com/tcl-installer/index.html     # 
[6] https://www.irontcl.com/                                # 
[6] https://www.activestate.com/products/tcl/downloads/     # 
[6] http://tclkits.rkeene.org/fossil/wiki/Downloads         # 
[6] http://kitcreator.rkeene.org/kitcreator                 # 

也许有人可以告诉我如何将它们导入到Python中?


有哪些后端可用?它们在哪里?

让我们通过以下一行代码来启发自己:

python.exe -c "import matplotlib as m; help(m);"
python.exe -c "import matplotlib as m; print('I: {}\nN: {}'.format(m.rcsetup.interactive_bk,m.rcsetup.non_interactive_bk));"

# I: ['GTK3Agg', 'GTK3Cairo', 'MacOSX', 'nbAgg', 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo', 'WebAgg', 'WX', 'WXAgg', 'WXCairo']
# N: ['agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template']

python.exe -c "import matplotlib as m; p=m.get_backend();print('current backend is:',p);"
# agg

python.exe -c "import matplotlib as m; p=m.matplotlib_fname(); print('The matplotlibrc is located at:\n',p);"
# C:\Python38\lib\site-packages\matplotlib\mpl-data\matplotlibrc

设置后端

正如文档所述:有三种配置后端的方式:

  1. 在你的matplotlibrc文件中设置rcParams["backend"](默认值:'agg')参数。
  2. 设置 MPLBACKEND 环境(shell)变量。
  3. 使用函数matplotlib.use()

使用后端

最终,使用可用的后端只需要做到这一点:

import matplotlib 
#matplotlib.use('tkagg', force=True)        # Agg rendering to a Tk canvas
#matplotlib.use('wxcairo', force=True)      # Cairo rendering to a wxWidgets canvas
#matplotlib.use('wxagg', force=True)        # Agg rendering to a wxWidgets canvas
matplotlib.use('webagg', force=True)        # On show() will start a tornado server with an interactive figure.

#matplotlib.use('qt5cairo', force=True)     # Cairo rendering to a Qt5 canvas
#matplotlib.use('qt5agg', force=True)       # Agg rendering to a Qt5 canvas

import matplotlib.pyplot as plt

这个答案对于使用Windows操作系统的人来说是非常有用的资源。 - Rolf of Saxony

7

如果您正在使用IPython控制台(包括在Spyder内部),则可以使用内置的魔术命令快速切换后端,例如:

%matplotlib qt

使用命令获取可用的后端列表:

%matplotlib --list

可用的matplotlib后端:['tk','gtk','gtk3','wx','qt4','qt5','qt','osx','nbagg','notebook','agg','svg','pdf','ps','inline','ipympl','widget']


6
在我的情况下(Windows 10 + Python 3.7),@Rolf of Saxony的第一个答案效果不是很好。相反,不要尝试所有可用的环境并在开始时配置其中一个, 即在

之后立即进行配置。
    import matplotlib

我必须通过以下方式将环境从'Agg'更改为'TkAgg'

    matplotlib.use('TKAgg',warn=False, force=True)

就在我实际绘图的代码之前,也就是说,

    import matplotlib.pyplot as plt
    fig = plt.figure()
    # AND SO ON....

6

要永久更改后端,可以使用以下方法:

  1. First locate the matplotlibrc file:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. Open the terminal and do:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. Edit the file (if it does not exist use this command: touch matplotlib to create it):

    vim matplotlibrc
    
  4. Add this line and save:

    backend: TkAgg
    

当我在程序中加入TkAgg时,它可以工作。但是当我在matplotlibrc中添加最后一行并且不在程序中指定后端时,它会给出TypeError错误。 - user187604

4

你也可以使用另一个Python进程制作该图表,可能需要pickle或joblib的帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接