Comment changer les backends dans matplotlib / Python

87

Je suis aux prises avec le problème suivant. J'ai besoin de générer des rapports qui consistent en une collection de graphiques. Tous ces graphiques, sauf un, sont créés à l'aide du backend par défaut de Matplotlib (TkAgg). Un graphique doit être créé en utilisant le backend Cairo, la raison en est que je trace un graphique igraph et qui ne peut être tracé qu'en utilisant Cairo.

Le problème est que je ne peux pas changer les backends à la volée, par exemple ce qui suit ne fonctionne pas:
matplotlib.pyplot.switch_backend('cairo.png') (je sais que la fonctionnalité switch_backend est expérimentale)

et j'ai également essayé, matplotlib.use("cairo.png")mais cela conduit à des problèmes d'importation car la matplotlib.use("cairo.png")déclaration doit venir avant l'importation matplotlib.pyplot. mais j'ai besoin de deux backends différents au cours de la vie du script.

Ma question est donc est-ce que quelqu'un a un extrait de code qui montre comment changer le backend dans Matplotlib?

Merci beaucoup!

MISE À JOUR: J'ai écrit un extrait de code qui charge matplotlib, montre le backend par défaut, décharge matplotlib, le recharge et change le 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()

mais est-ce vraiment la façon de procéder?

MISE À JOUR 2: J'ai eu un sérieux gel du cerveau hier ... La solution simple et la plus évidente est d'utiliser le backend Cairo pour tous les graphiques et de ne pas changer de backend du tout :)

MISE À JOUR 3: En fait, c'est toujours un problème donc quiconque sait comment changer dynamiquement les backends matplotlib .... s'il vous plaît poster votre réponse.

DrDee
la source
Il y a pyplot.switch_backends(). Cela pourrait ne pas fonctionner dans votre cas.
jfs

Réponses:

59

Six ans plus tard, je suis tombé sur un problème similaire, en essayant de décider lequel backendétait disponible.
Cet extrait de code fonctionne bien pour moi:

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

Comme vous pouvez le déduire, permuter le backendest aussi simple que de réimporter matplotlib.pyplotaprès avoir forcé le nouveaubackend

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

Switched to: WXAgg

Pour ceux qui ont encore des problèmes, ce code imprimera: la
liste des backends Non Gui;
la liste des backends Gui;
puis essayez d'utiliser chaque backend Gui pour voir s'il est présent et fonctionne.

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 de Saxe
la source
Merci! Cela a très bien fonctionné pour m'aider à trouver le back-end approprié pour cet exemple: stackoverflow.com/questions/11874767/...
James Nelson
Rolf of Saxony, LOL très utile, je reçois toujours des réponses sur Ubuntu et Android post d'il y a près d'une décennie.
James Nelson
37

Il existe une fonctionnalité "expérimentale":

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

extrait de matplotlib doc .

Basculez le backend par défaut sur newbackend. Cette fonctionnalité est expérimentale et ne devrait fonctionner que lors du passage à un backend image. Par exemple, si vous avez un tas de scripts PostScript que vous souhaitez exécuter à partir d'une session ipython interactive, vous pouvez basculer vers le backend PS avant de les exécuter pour éviter d'avoir un tas de fenêtres contextuelles GUI. Si vous essayez de passer de manière interactive d'un backend GUI à un autre, vous exploserez. L'appel de cette commande fermera toutes les fenêtres ouvertes.

oyo
la source
Chaîne de backend non reconnue "newbackend". Que devrais-je faire?
TSR
4
@TSR Remplacez 'newbackend' par un backend GUI tel que 'Qt4Agg'
YashTD
14

Pourquoi ne pas simplement utiliser la reloadfonction intégrée ( importlib.reloaden Python 3)?

import matplotlib
matplotlib.use('agg')

matplotlib = reload(matplotlib)
matplotlib.use('cairo.png')
Fredbaba
la source
Comme dans vous ne pouvez pas recharger matplotlib et matplotlib.pyplot? Ou dites-vous simplement que mon code extrait est incomplet?
fredbaba
Hmm. Cela aurait peut-être été une bizarrerie d'IPython. Semble bien fonctionner dans la console standard.
Mad Physicist
1
Je pense que c'est un exemple qui montre que cela ne fonctionne pas: python -c "import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"est-ce exact?
Lukas
6

Je ne suis donc pas tout à fait sûr que ce soit ce que vous recherchez.

Vous pouvez changer votre backend via le fichier matplotlibrc qui contient certaines configurations pour votre matplotlib.

Dans votre script, vous pouvez mettre:

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

ou quelque chose comme ça pour basculer entre les backends.

fonction d'aide
la source
2
En effet, vous pouvez spécifier le backend dans votre dictionnaire rcParams mais cela ne résout pas le problème du passage d'un backend à un autre.
DrDee
vous pouvez également définir le backend par défaut dans le fichier de configuration qui est récupéré par matplotlib:~/.config/matplotlib/matplotlibrc
scrutari
4

Dans mon cas (Windows 10 + python 3.7), la première réponse de @Rolf of Saxony n'a pas très bien fonctionné. Au lieu d'essayer tous les environnements disponibles et de configurer l'un d'entre eux au début, c'est-à-dire juste après

    import matplotlib

J'ai dû changer l'environnement de 'Agg' à 'TkAgg' en utilisant

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

juste avant le code où j'ai réellement tracé, c'est-à-dire

    import matplotlib.pyplot as plt
    fig = plt.figure()
    # AND SO ON....
Pe Dro
la source
2

Pour modifier définitivement le backend, vous pouvez utiliser ceci:

  1. Localisez d'abord le matplotlibrcfichier:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. Ouvrez le terminal et faites:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. Editez le fichier (s'il n'existe pas utilisez cette commande: touch matplotlibpour le créer):

    vim matplotlibrc
    
  4. Ajoutez cette ligne et enregistrez:

    backend: TkAgg
    
seralouk
la source
1

Vous pouvez également demander à un autre processus Python de créer ce tracé, éventuellement à l'aide de pickle ou de joblib .

Ken Arnold
la source
0

Si vous utilisez une console IPython (y compris dans Spyder), vous pouvez utiliser des commandes magiques intégrées pour changer rapidement de backends, par exemple:

%matplotlib qt

Obtenez une liste des backends disponibles à utiliser avec la commande:

%matplotlib --list

Backends matplotlib disponibles: ['tk', 'gtk', 'gtk3', 'wx', 'qt4', 'qt5', 'qt', 'osx', 'nbagg', 'notebook', 'agg', ' svg ',' pdf ',' ps ',' inline ',' ipympl ',' widget ']

Mike T
la source