Come cambiare i backend in matplotlib / Python


90

Sto lottando con il seguente problema. Devo generare rapporti che consistono in una raccolta di grafici. Tutti questi grafici, tranne uno, sono realizzati utilizzando il backend predefinito di Matplotlib (TkAgg). Un grafico deve essere creato utilizzando il backend Cairo, il motivo è che sto tracciando un grafico igraph e che può essere tracciato solo utilizzando Cairo.

Il problema è che non posso modificare i backend al volo, ad esempio quanto segue non funziona:
matplotlib.pyplot.switch_backend('cairo.png') (So ​​che la funzionalità switch_backend è sperimentale)

e ho anche provato, matplotlib.use("cairo.png")ma questo porta a problemi di importazione poiché l' matplotlib.use("cairo.png")istruzione dovrebbe venire prima dell'importazione matplotlib.pyplot. ma ho bisogno di due diversi backend nel corso della vita della sceneggiatura.

Quindi la mia domanda è: qualcuno ha uno snippet di codice che mostra come cambiare il backend in Matplotlib?

Grazie mille!

AGGIORNAMENTO: ho scritto uno snippet che carica matplotlib, mostra il backend predefinito, scarica matplotlib, lo ricarica e cambia il backend:

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

ma è davvero questo il modo per farlo?

AGGIORNAMENTO 2: ieri ho avuto un serio congelamento del cervello ... La soluzione semplice e più ovvia è usare il backend Cairo per tutti i grafici e non cambiare affatto il backend :)

AGGIORNAMENTO 3: In realtà, è ancora un problema, quindi chiunque sappia come cambiare dinamicamente i backend matplotlib .... per favore pubblica la tua risposta.


C'è pyplot.switch_backends(). Potrebbe non funzionare nel tuo caso.
jfs

Risposte:


60

Sei anni dopo mi sono imbattuto in un problema simile, cercando di decidere quale backendfosse disponibile per l'uso.
Nota vedere Avvertenze - sotto

Questo snippet di codice funziona bene per me:

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

Come puoi dedurre, scambiare il file backendè semplice come reimportare matplotlib.pyplotdopo aver forzato il nuovobackend

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

Switched to: WXAgg

Per coloro che hanno ancora problemi, questo codice stamperà: l'
elenco dei backend non Gui;
l'elenco dei backend Gui;
e quindi provare a utilizzare ciascun backend Gui per vedere se è presente e funzionante.

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

Avvertenze: modifiche in matplotlib dalla versione 3.3.0

  • Il primo parametro di matplotlib.use è stato rinominato da arg a backend (rilevante solo se passi per parola chiave).
  • Il parametro warn di matplotlib.use è stato rimosso. Un errore nel cambiare il backend ora solleverà sempre un ImportError se force è impostato; rilevare l'errore se necessario.
  • Tutti i parametri di matplotlib.use tranne il primo ora sono solo parole chiave.

Grazie! Ha funzionato alla grande aiutandomi a trovare il back-end appropriato per questo esempio: stackoverflow.com/questions/11874767/…
James Nelson

Rolf di Sassonia, LOL molto utile, ricevo ancora risposte su Ubuntu e post Android da quasi dieci anni fa.
James Nelson

L' warn=Falseargomento non è più disponibile.
not2qubit

@ not2qubit Notato - grazie. Avvertenze aggiunte.
Rolf di Sassonia

37

C'è una funzione "sperimentale":

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

tratto da matplotlib doc .

Cambia il backend predefinito in newbackend. Questa funzione è sperimentale e dovrebbe funzionare solo passando a un backend di immagini. Ad esempio, se hai un sacco di script PostScript che vuoi eseguire da una sessione ipython interattiva, potresti voler passare al backend PS prima di eseguirli per evitare di avere un mucchio di finestre popup della GUI. Se provi a passare in modo interattivo da un backend della GUI a un altro, esploderai. La chiamata a questo comando chiuderà tutte le finestre aperte.


Stringa di backend non riconosciuta "newbackend". Cosa dovrei fare?
TSR

5
@TSR Sostituisci 'newbackend' con un backend GUI come 'Qt4Agg'
YashTD

14

Perché non usare semplicemente la reloadfunzione incorporata ( importlib.reloadin Python 3)?

import matplotlib
matplotlib.use('agg')

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

Come in non puoi ricaricare matplotlib e matplotlib.pyplot? O stai solo dicendo che il mio codice ritagliato è incompleto?
fredbaba

Hmm. Potrebbe essere stato effettivamente un capriccio di IPython. Sembra funzionare bene nella console normale.
Mad Physicist

1
Penso che questo sia un esempio, che dimostri che non funziona: python -c "import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"è vero?
Lukas

6

Quindi non sono completamente sicuro che questo sia quello che stai cercando.

Puoi cambiare il tuo backend attraverso il file matplotlibrc che contiene alcune configurazioni per il tuo matplotlib.

Nel tuo script puoi inserire:

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

o qualcosa del genere per passare da un backend all'altro.


2
In effetti, puoi specificare il backend nel tuo dizionario rcParams ma questo non risolve il problema del passaggio da un backend a un altro.
DrDee

puoi anche impostare il backend predefinito nel file di configurazione che viene raccolto da matplotlib:~/.config/matplotlib/matplotlibrc
scrutari

4

Nel mio caso (Windows 10 + python 3.7), la prima risposta di @Rolf di Sassonia non ha funzionato molto bene. Invece di provare tutti gli ambienti disponibili e configurarne uno all'inizio, cioè subito dopo

    import matplotlib

Ho dovuto cambiare l'ambiente da "Agg" a "TkAgg" usando

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

subito prima del codice su cui ho effettivamente tracciato, ovvero

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

2

Per cambiare definitivamente il backend puoi usare questo:

  1. Per prima cosa individua il matplotlibrcfile:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. Apri il terminale e fai:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. Modifica il file (se non esiste usa questo comando: touch matplotlibper crearlo):

    vim matplotlibrc
    
  4. Aggiungi questa riga e salva:

    backend: TkAgg
    


0

Se stai usando una console IPython (incluso all'interno di Spyder) puoi usare i comandi magici incorporati per cambiare rapidamente backend, ad esempio:

%matplotlib qt

Ottieni un elenco di backend disponibili da utilizzare con il comando:

%matplotlib --list

Backend matplotlib disponibili: ["tk", "gtk", "gtk3", "wx", "qt4", "qt5", "qt", "osx", "nbagg", "notebook", "agg", " svg "," pdf "," ps "," inline "," ipympl "," widget "]


0

Extra Info

Sebbene ognuno mostri il proprio back-end preferito, è piuttosto complicato capire cosa è necessario installare e quali sono i requisiti. Almeno quando si cerca di capire la documentazione generalmente confusa e tecnocratica. Oggi ho fatto diversi esperimenti e penso di aver trovato le soluzioni più semplici per ogni back-end per poter stampare con matplotlib in Windows e utilizzando Py3.8.5 (senza Qt integrato). Ecco i miei risultati:

#--------------------------------------
# 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]

Ecco i link a tutti quei PyPi o Repos:

[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

Tuttavia, e molto sorprendente data la grande quantità di documentazione per l'utilizzo Tcl/Tke i tkinterpacchetti per python, non sono stato in grado di installarlo, né trovare istruzioni utili su come importare le DLL in python. (Per Linux questo è banale dato che usi solo il gestore di pacchetti del sistema operativo apt-get install <tk-what-not>, ma questa opzione non è disponibile per Windows, né esiste un semplice analogo. Ecco un elenco dei molti e vari binari che puoi ottenere.

[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                 # 

Forse qualcuno mi può illuminare su come ottenere uno di questi importati in Python?


What backends are available and where?

Illuminiamoci con le seguenti battute:

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

Setting the back-end

Come dice la documentazione: ci sono 3 modi per configurare il tuo backend:

  1. Impostazione del rcParams["backend"]parametro (predefinito: 'agg') nel tuo matplotlibrc file
  2. L'impostazione di MPLBACKEND variabile di ambiente (shell)
  3. Utilizzo della funzione matplotlib.use()

Using the backend

Infine, per utilizzare il tuo backend disponibile è solo questione di fare questo:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.