Bagaimana mengubah backend di matplotlib / Python

90

Saya berjuang dengan masalah berikut. Saya perlu membuat laporan yang terdiri dari kumpulan grafik. Semua grafik ini, kecuali satu, dibuat menggunakan backend default Matplotlib (TkAgg). Satu grafik perlu dibuat menggunakan backend Kairo, alasannya adalah saya sedang memplot grafik igraph dan itu hanya dapat diplot menggunakan Kairo.

Masalahnya adalah saya tidak dapat mengubah backend dengan cepat, misalnya berikut ini tidak berfungsi:
matplotlib.pyplot.switch_backend('cairo.png') (Saya tahu bahwa fungsi switch_backend bersifat eksperimental)

dan saya juga telah mencoba matplotlib.use("cairo.png")tetapi ini menyebabkan masalah impor karena matplotlib.use("cairo.png")pernyataan tersebut harus ada sebelum mengimpor matplotlib.pyplot. tetapi saya membutuhkan dua backend yang berbeda selama masa pakai skrip.

Jadi pertanyaan saya adalah apakah seseorang memiliki potongan kode yang menunjukkan cara mengganti backend di Matplotlib?

Terima kasih banyak!

UPDATE: Saya telah menulis cuplikan yang memuat matplotlib, menunjukkan backend default, membongkar matplotlib, memuatnya kembali dan mengubah 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()

tetapi apakah ini benar-benar cara untuk melakukannya?

PEMBARUAN 2: Saya mengalami pembekuan otak yang serius kemarin ... Solusi sederhana dan paling jelas adalah menggunakan backend Kairo untuk semua grafik dan tidak mengganti backend sama sekali :)

PEMBARUAN 3: Sebenarnya, ini masih menjadi masalah, jadi siapa pun yang tahu cara mengganti backend matplotlib secara dinamis .... silakan kirim jawaban Anda.

DrDee
sumber
Ada pyplot.switch_backends(). Ini mungkin tidak berhasil dalam kasus Anda.
jfs

Jawaban:

60

Enam tahun kemudian dan saya menemukan masalah serupa, ketika mencoba memutuskan mana backendyang tersedia untuk digunakan.
Perhatikan, lihat Peringatan - di bawah

Cuplikan kode ini berfungsi dengan baik untuk saya:

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

Seperti yang dapat Anda simpulkan, menukar backenditu semudah mengimpor ulang matplotlib.pyplotsetelah memaksakan yang barubackend

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

Switched to: WXAgg

Bagi mereka yang masih mengalami masalah, kode ini akan mencetak:
daftar backend Non Gui;
daftar backend Gui;
lalu coba gunakan setiap backend Gui untuk melihat apakah ada dan berfungsi.

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

Peringatan: Perubahan dalam matplotlib sejak versi 3.3.0

  • Parameter pertama matplotlib.use telah diganti namanya dari arg menjadi backend (hanya relevan jika Anda meneruskan kata kunci).
  • Parameter memperingatkan matplotlib.use telah dihapus. Kegagalan untuk mengganti backend sekarang akan selalu memunculkan ImportError jika gaya disetel; tangkap kesalahan itu jika perlu.
  • Semua parameter matplotlib.use kecuali yang pertama sekarang hanya kata kunci.
Rolf dari Saxony
sumber
Terima kasih! Ini bekerja sangat baik membantu saya menemukan back-end yang sesuai untuk contoh ini: stackoverflow.com/questions/11874767/…
James Nelson
Rolf dari Saxony, LOL sangat membantu, saya masih mendapatkan tanggapan di Ubuntu dan Android posting hampir satu dekade yang lalu.
James Nelson
The warn=FalseArgumen tidak lagi tersedia.
not2qubit
@ not2qubit Tercatat - terima kasih. Peringatan ditambahkan.
Rolf dari Saxony
37

Ada fitur "eksperimental":

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

diambil dari matplotlib doc .

Alihkan backend default ke backend baru. Fitur ini bersifat eksperimental , dan diharapkan berfungsi hanya dengan beralih ke backend gambar. Misalnya, jika Anda memiliki banyak skrip PostScript yang ingin Anda jalankan dari sesi ipython interaktif, Anda mungkin ingin beralih ke backend PS sebelum menjalankannya untuk menghindari banyaknya jendela popup GUI. Jika Anda mencoba beralih secara interaktif dari satu backend GUI ke yang lain, Anda akan meledak. Memanggil perintah ini akan menutup semua jendela yang terbuka.

oyo
sumber
String backend "newbackend" tidak dikenal. Apa yang harus saya lakukan?
TSR
5
@TSR Ganti 'newbackend' dengan GUI backend seperti 'Qt4Agg'
YashTD
14

Mengapa tidak menggunakan saja reloadfungsi bawaan ( importlib.reloaddengan Python 3)?

import matplotlib
matplotlib.use('agg')

matplotlib = reload(matplotlib)
matplotlib.use('cairo.png')
fredbaba
sumber
Seperti Anda tidak dapat memuat ulang matplotlib dan matplotlib.pyplot? Atau apakah Anda hanya mengatakan bahwa kode saya yang dipotong tidak lengkap?
fredbaba
Hmm. Mungkin sebenarnya merupakan kekhasan dari IPython. Sepertinya bekerja dengan baik di konsol biasa.
Fisikawan Gila
1
Saya pikir ini adalah contoh, yang menunjukkan, bahwa itu tidak berhasil: python -c "import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"Apakah itu benar?
Lukas
6

Jadi saya tidak sepenuhnya yakin apakah ini yang Anda cari.

Anda dapat mengubah backend Anda melalui file matplotlibrc yang berisi konfigurasi tertentu untuk matplotlib Anda.

Dalam skrip Anda, Anda dapat memasukkan:

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

atau sesuatu seperti itu untuk beralih di antara backend.

fungsi pembantu
sumber
2
Memang, Anda dapat menentukan backend di kamus rcParams Anda tetapi itu tidak menyelesaikan masalah peralihan dari satu backend ke backend lainnya.
DrDee
Anda juga dapat mengatur backend default dalam file konfigurasi yang diambil oleh matplotlib:~/.config/matplotlib/matplotlibrc
scrutari
4

Dalam kasus saya (Windows 10 + python 3.7), jawaban pertama oleh @Rolf dari Saxony tidak berfungsi dengan baik. Alih-alih mencoba semua lingkungan yang tersedia dan mengkonfigurasi salah satunya di awal, yaitu, setelahnya

    import matplotlib

Saya harus mengubah lingkungan dari 'Agg' menjadi 'TkAgg' menggunakan

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

tepat sebelum kode yang sebenarnya saya buat, yaitu,

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

Untuk mengubah backend secara permanen, Anda dapat menggunakan ini:

  1. Pertama cari matplotlibrcfile:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. Buka terminal dan lakukan:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. Edit file (jika tidak ada gunakan perintah ini: touch matplotlibuntuk membuatnya):

    vim matplotlibrc
    
  4. Tambahkan baris ini dan simpan:

    backend: TkAgg
    
seralouk
sumber
1

Anda juga dapat menggunakan proses Python yang berbeda untuk membuat plot itu, mungkin dengan bantuan acar atau joblib .

Ken Arnold
sumber
0

Jika Anda menggunakan konsol IPython (termasuk di dalam Spyder) Anda dapat menggunakan perintah ajaib bawaan untuk beralih backend dengan cepat, misalnya:

%matplotlib qt

Dapatkan daftar backend yang tersedia untuk digunakan dengan perintah:

%matplotlib --list

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

Mike T
sumber
0

Extra Info

Meskipun semua orang menunjukkan back-end favorit mereka sendiri, cukup berantakan untuk mencari tahu apa yang perlu Anda instal dan apa persyaratannya. Setidaknya ketika Anda mencoba untuk memahami dokumentasi yang umumnya membingungkan dan teknokratis. Hari ini saya telah melakukan beberapa percobaan dan berpikir saya telah menemukan solusi paling sederhana untuk setiap back-end agar dapat memplot dengan matplotlib di Windows dan menggunakan Py3.8.5 (tanpa Qt built-in). Inilah temuan saya:

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

Berikut adalah tautan ke semua PyPi atau Repos itu:

[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

Namun, dan sangat mengejutkan mengingat banyaknya dokumentasi untuk digunakan Tcl/Tkdan tkinterpaket untuk python, saya tidak dapat menginstalnya, atau menemukan instruksi yang berguna tentang cara mengimpor DLL ke python. (Untuk linux ini sepele karena Anda hanya menggunakan pengelola paket OS apt-get install <tk-what-not>, tetapi opsi ini tidak tersedia untuk windows, juga tidak ada analog sederhana. Berikut adalah daftar dari banyak dan berbagai binari yang bisa Anda dapatkan.

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

Mungkin seseorang bisa mencerahkan saya bagaimana cara mengimpor ini ke python?


What backends are available and where?

Mari mencerahkan diri kita dengan satu kalimat berikut:

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

Seperti yang disebutkan dalam dokumentasi: Ada 3 cara untuk mengonfigurasi backend Anda:

  1. Menyetel rcParams["backend"]parameter (default: 'agg') di file matplotlibrc Anda
  2. Mengatur MPLBACKENDvariabel lingkungan (shell)
  3. Menggunakan fungsi tersebut matplotlib.use()

Using the backend

Terakhir, untuk menggunakan backend Anda yang tersedia hanyalah masalah melakukan ini:

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
not2qubit
sumber