如何更改matplotlib后端

107 投票
9 回答
139161 浏览
提问于 2025-04-16 01:32

我遇到了一个问题。我需要生成包含多个图表的报告。除了一个图表外,其他所有图表都是用Matplotlib的默认后端(TkAgg)制作的。那个特殊的图表需要用Cairo后端来制作,因为我在绘制一个igraph图,而这个图只能用Cairo来绘制。

问题是我不能随时切换后端,比如下面的代码是无法工作的:
matplotlib.pyplot.switch_backend('cairo.png') (我知道这个切换后端的功能还在实验阶段)

我也尝试过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后端……请分享你的答案。

9 个回答

16

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

import matplotlib
matplotlib.use('agg')

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

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

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

摘自 matplotlib 文档

这个功能可以把默认的后端切换到新的后端。这个功能是实验性的,目前只预计能在切换到图像后端时正常工作。比如说,如果你有一堆 PostScript 脚本,想在交互式的 ipython 会话中运行这些脚本,你可能想在运行之前切换到 PS 后端,这样就不会弹出一堆图形界面的窗口。如果你尝试在不同的图形界面后端之间进行切换,可能会出现问题。执行这个命令会关闭所有打开的窗口。

81

六年后,我遇到了一个类似的问题,想要决定哪个 backend 可以使用。
注意查看下面的注意事项

这个代码片段对我来说效果很好:

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

对于那些仍然遇到问题的人,这段代码会打印出:
非图形界面(Non 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")

注意事项:自版本 3.3.0 起,matplotlib 的变化

  • matplotlib.use 的第一个参数已经从 arg 改名为 backend(如果你通过关键字传递,这一点很重要)。
  • matplotlib.use 的 warn 参数已被移除。如果切换后端失败,设置为强制时将始终引发 ImportError;如果需要,请捕获这个错误。
  • matplotlib.use 的所有参数(除了第一个)现在只能通过关键字传递。

撰写回答