Como alterar back-ends em matplotlib / Python

87

Estou lutando com o seguinte problema. Preciso gerar relatórios que consistam em uma coleção de gráficos. Todos esses gráficos, exceto um, são feitos usando o backend padrão do Matplotlib (TkAgg). Um gráfico precisa ser feito usando o back-end do Cairo, a razão é que estou traçando um gráfico igraph e que só pode ser traçado usando o Cairo.

O problema é que não consigo alterar back-ends dinamicamente, por exemplo, o seguinte não funciona:
matplotlib.pyplot.switch_backend('cairo.png') (sei que a funcionalidade switch_backend é experimental)

e eu também tentei, matplotlib.use("cairo.png")mas isso leva a problemas de importação como omatplotlib.use("cairo.png") instrução deve vir antes da importação matplotlib.pyplot. mas preciso de dois back-ends diferentes ao longo da vida do script.

Então, minha pergunta é se alguém tem um trecho de código que mostra como alternar o back-end no Matplotlib?

Muito obrigado!

ATUALIZAÇÃO: escrevi um snippet que carrega matplotlib, mostra o back-end padrão, descarrega matplotlib, recarrega e altera o back-end:

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()

mas essa é realmente a maneira de fazer isso?

ATUALIZAÇÃO 2: Eu tive um congelamento cerebral sério ontem ... A solução simples e mais óbvia é usar o back-end do Cairo para todos os gráficos e não mudar o back-end de forma alguma :)

ATUALIZAÇÃO 3: Na verdade, ainda é um problema, então qualquer pessoa que saiba como alternar dinamicamente os back-ends do matplotlib ... por favor, poste sua resposta.

DrDee
fonte
Existe pyplot.switch_backends(). Pode não funcionar no seu caso.
jfs

Respostas:

59

Seis anos depois, me deparei com um problema semelhante, ao tentar decidir qual backendestava disponível para uso.
Este snippet de código funciona bem para mim:

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

Como você pode deduzir, trocar o backendé tão simples quanto reimportar matplotlib.pyplotdepois de forçar o novobackend

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

Switched to: WXAgg

Para aqueles que ainda estão tendo problemas, este código irá imprimir a:
lista de back-ends não Gui;
a lista de back-ends do Gui;
e tente usar cada back-end Gui para ver se ele está presente e funcionando.

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")
Rolf da Saxônia
fonte
Obrigado! Isso funcionou muito bem, ajudando-me a encontrar o back-end apropriado para este exemplo: stackoverflow.com/questions/11874767/…
James Nelson
Rolf da Saxônia, LOL muito útil, ainda recebo respostas no Ubuntu e Android postando de quase uma década atrás.
James Nelson de
37

Existe um recurso "experimental":

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

retirado do doc matplotlib .

Mude o back-end padrão para newbackend. Este recurso é experimental e só deve funcionar alternando para um back-end de imagem. Por exemplo, se você tem um monte de scripts PostScript que deseja executar em uma sessão ipython interativa, pode querer alternar para o back-end PS antes de executá-los para evitar ter um monte de janelas pop-up da GUI. Se você tentar alternar interativamente de um back-end GUI para outro, você explodirá. Chamar este comando fechará todas as janelas abertas.

oyo
fonte
String de back-end não reconhecida "newbackend". O que devo fazer?
TSR
4
@TSR Substitua 'newbackend' por um backend GUI, como 'Qt4Agg'
YashTD
14

Por que não apenas usar a reloadfunção importlib.reloadinterna ( no Python 3)?

import matplotlib
matplotlib.use('agg')

matplotlib = reload(matplotlib)
matplotlib.use('cairo.png')
Fredbaba
fonte
Como em você não pode recarregar matplotlib e matplotlib.pyplot? Ou você está apenas dizendo que meu código cortado está incompleto?
fredbaba
Hmm. Pode ter sido uma peculiaridade do IPython. Parece funcionar bem no console regular.
Mad Physicist
1
Eu acho que é um exemplo, que mostra que não funciona: python -c "import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"é isso?
Lukas
6

Portanto, não tenho certeza se é isso que você está procurando.

Você pode alterar seu backend através do arquivo matplotlibrc que contém certas configurações para seu matplotlib.

Em seu script você pode colocar:

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

ou algo parecido para alternar entre back-ends.

função auxiliar
fonte
2
Na verdade, você pode especificar o backend em seu dicionário rcParams, mas isso não resolve o problema de alternar de um backend para outro.
DrDee
você também pode definir o backend padrão no arquivo de configuração que é obtido por matplotlib:~/.config/matplotlib/matplotlibrc
scrutari
4

No meu caso (Windows 10 + python 3.7), a primeira resposta de @Rolf da Saxônia não funcionou muito bem. Em vez de tentar todos os ambientes disponíveis e configurar um deles no início, ou seja, logo após

    import matplotlib

Tive que mudar o ambiente de 'Agg' para 'TkAgg' usando

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

logo antes do código onde eu realmente plotei, ou seja,

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

Para alterar permanentemente o back-end, você pode usar isto:

  1. Primeiro localize o matplotlibrcarquivo:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. Abra o terminal e faça:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. Edite o arquivo (se não existir use este comando: touch matplotlibpara criá-lo):

    vim matplotlibrc
    
  4. Adicione esta linha e salve:

    backend: TkAgg
    
Seralouk
fonte
1

Você também pode ter um processo Python diferente para fazer esse gráfico, possivelmente com a ajuda de pickle ou joblib .

Ken Arnold
fonte
0

Se você estiver usando um console IPython (inclusive no Spyder), poderá usar comandos mágicos integrados para alternar rapidamente os back-ends, por exemplo:

%matplotlib qt

Obtenha uma lista de back-ends disponíveis para usar com o comando:

%matplotlib --list

Back-ends de matplotlib disponíveis: ['tk', 'gtk', 'gtk3', 'wx', 'qt4', 'qt5', 'qt', 'osx', 'nbagg', 'notebook', 'agg', ' svg ',' pdf ',' ps ',' inline ',' ipympl ',' widget ']

Mike T
fonte