Как переключить backend в matplotlib/Python

Я борюсь со следующей проблемой. Мне нужно создать отчеты, которые состоят из набора диаграмм. Все эти диаграммы, кроме одного, создаются с использованием базового компонента Matplotlib по умолчанию (TkAgg). Одна диаграмма должна быть сделана с использованием Cairo-бэкэнд, причина в том, что я рисую график играфа, и это можно сделать только с использованием Каира.

Проблема заключается в том, что я не могу менять серверы "на лету", например, следующее не работает:
  matplotlib.pyplot.switch_backend('cairo.png') (Я знаю, что функция switch_backend экспериментальна)

и я также пробовал matplotlib.use("cairo.png"), но это приводит к проблемам с импортом, поскольку оператор matplotlib.use("cairo.png") должен появиться перед импортом matplotlib.pyplot. но мне нужно два разных бэкенда в течение жизни script.

Итак, мой вопрос в том, есть ли у кого-нибудь фрагмент кода, который показывает, как переключить сервер в Matplotlib?

Большое спасибо!

UPDATE: Я написал фрагмент, который загружает 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...., пожалуйста, напишите свой ответ.

Ответ 1

Шесть лет спустя, и я столкнулся с подобной проблемой, пытаясь решить, какой 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 так же просто, как повторный импорт matplotlib.pyplot после форсирования нового backend

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

Switched to: WXAgg

Для тех, у кого по-прежнему возникают проблемы, этот код будет распечатывать:
список небанковских бэкэндов,
список Gui backends,
а затем попытайтесь использовать каждый бэкэнд 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")

Ответ 2

Есть "экспериментальная" функция:

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

взято из matplotlib док.

Переключите бэкэнд по умолчанию на newbackend. Эта функция является экспериментальной, и ожидается, что она будет работать только при переключении на бэкэнд изображения. Например, если у вас есть несколько сценариев PostScript, которые вы хотите запустить из интерактивного сеанса ipython, вы, возможно, захотите переключиться на серверную часть PS перед запуском, чтобы избежать появления всплывающих окон GUI. Если вы попытаетесь интерактивно переключиться с одного интерфейса GUI на другой, вы взорветесь. Вызов этой команды закроет все открытые окна.

Ответ 3

Почему бы просто не использовать встроенную функцию reload ( importlib.reload в Python 3)?

import matplotlib
matplotlib.use('agg')

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

Ответ 4

Поэтому я не совсем уверен, что это то, что вы ищете.

Вы можете изменить свой backend через файл matplotlibrc, который содержит определенные конфигурации для вашего matplotlib.

В script вы можете поставить:

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

или что-то вроде этого, чтобы переключаться между бэкэндами.

Ответ 5

У вас также может быть другой процесс Python, чтобы сделать этот график, возможно, с помощью pickle или joblib.

Ответ 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....

Ответ 7

Чтобы навсегда изменить бэкэнд, вы можете использовать это:

  1. Сначала найдите файл matplotlibrc:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. Откройте терминал и выполните:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. Отредактируйте файл (если он не существует, используйте touch matplotlib для его создания):

    vim matplotlibrc
    
  4. Добавьте эту строку и сохраните:

    backend: TkAgg