Zmagam się z następującym problemem. Muszę wygenerować raporty składające się ze zbioru wykresów. Wszystkie te wykresy, z wyjątkiem jednego, są tworzone przy użyciu domyślnego zaplecza Matplotlib (TkAgg). Jeden wykres musi zostać utworzony przy użyciu zaplecza Cairo, ponieważ kreślę wykres igraph, który można wykreślić tylko za pomocą Cairo.
Problem polega na tym, że nie mogę zmienić backendów w locie, na przykład nie działa:
matplotlib.pyplot.switch_backend('cairo.png')
(wiem, że funkcja switch_backend jest eksperymentalna)
i próbowałem również, matplotlib.use("cairo.png")
ale prowadzi to do problemów z importem, ponieważ matplotlib.use("cairo.png")
instrukcja powinna pojawić się przed importem matplotlib.pyplot
. ale potrzebuję dwóch różnych backendów w trakcie życia skryptu.
Więc moje pytanie brzmi: czy ktoś ma fragment kodu, który pokazuje, jak przełączyć zaplecze w Matplotlib?
Dzięki wielkie!
AKTUALIZACJA: Napisałem fragment, który ładuje matplotlib, pokazuje domyślny backend, zwalnia matplotlib, przeładowuje go i zmienia 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()
ale czy to naprawdę jest sposób na zrobienie tego?
AKTUALIZACJA 2: Wczoraj miałem poważne zamrożenie mózgu ... Prostym i najbardziej oczywistym rozwiązaniem jest użycie backendu Cairo do wszystkich wykresów i nie przełączanie backendu w ogóle :)
AKTUALIZACJA 3: Właściwie nadal jest to problem, więc każdy, kto wie, jak dynamicznie przełączać backendy matplotlib ... proszę opublikować swoją odpowiedź.
źródło
pyplot.switch_backends()
. To może nie działać w Twoim przypadku.Odpowiedzi:
Sześć lat później natknąłem się na podobny problem, próbując zdecydować, który z nich
backend
był dostępny.Uwaga, patrz Zastrzeżenia - poniżej
Ten fragment kodu działa dobrze dla mnie:
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
Jak możesz wywnioskować, zamiana pliku
backend
jest tak prosta, jak ponowne zaimportowaniematplotlib.pyplot
po wymuszeniu nowegobackend
matplotlib.use('WXAgg',warn=False, force=True) from matplotlib import pyplot as plt print "Switched to:",matplotlib.get_backend() Switched to: WXAgg
Dla tych, którzy nadal mają problemy, ten kod wydrukuje:
listę backendów Non Gui;
lista backendów Gui;
a następnie spróbuj użyć każdego zaplecza Gui, aby sprawdzić, czy jest obecny i działa.
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")
Ostrzeżenia: zmiany w matplotlib od wersji 3.3.0
źródło
warn=False
Argumentem nie jest już dostępny.Istnieje funkcja „eksperymentalna”:
import matplotlib.pyplot as plt plt.switch_backend('newbackend')
zaczerpnięte z matplotlib doc .
źródło
Dlaczego nie skorzystać po prostu z funkcji
reload
wbudowanej (importlib.reload
w Pythonie 3)?import matplotlib matplotlib.use('agg') matplotlib = reload(matplotlib) matplotlib.use('cairo.png')
źródło
python -c "import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"
Czy to prawda?Więc nie jestem do końca pewien, czy tego właśnie szukasz.
Możesz zmienić swój backend za pomocą pliku matplotlibrc, który zawiera określone konfiguracje dla twojego matplotlib.
W swoim skrypcie możesz umieścić:
matplotlib.rcParams['backend'] = 'TkAgg'
lub coś w tym rodzaju, aby przełączać się między backendami.
źródło
~/.config/matplotlib/matplotlibrc
W moim przypadku (Windows 10 + python 3.7) pierwsza odpowiedź autorstwa @Rolfa z Saksonii nie zadziałała zbyt dobrze. Zamiast wypróbowywać wszystkie dostępne środowiska i konfigurować jedno z nich na początku, czyli zaraz potem
import matplotlib
Musiałem zmienić środowisko z „Agg” na „TkAgg” za pomocą
matplotlib.use('TKAgg',warn=False, force=True)
tuż przed kodem, w którym wykreśliłem, tj.
import matplotlib.pyplot as plt fig = plt.figure() # AND SO ON....
źródło
Aby trwale zmienić backend, możesz użyć tego:
Najpierw zlokalizuj
matplotlibrc
plik:import matplotlib matplotlib.matplotlib_fname() # '/Users/serafeim/.matplotlib/matplotlibrc'
Otwórz terminal i wykonaj:
Edytuj plik (jeśli nie istnieje, użyj tego polecenia:
touch matplotlib
aby go utworzyć):Dodaj tę linię i zapisz:
źródło
Możesz także mieć inny proces w Pythonie, który tworzy ten wykres, być może przy pomocy pickle lub joblib .
źródło
Jeśli używasz konsoli IPython (w tym w Spyder), możesz użyć wbudowanych magicznych poleceń, aby szybko przełączać backendy, np:
Uzyskaj listę dostępnych backendów do użycia z poleceniem:
%matplotlib --list
źródło
Extra Info
Chociaż każdy pokazuje swoje ulubione zaplecze, dość kłopotliwe jest ustalenie, co należy zainstalować i jakie są wymagania. Przynajmniej wtedy, gdy spróbujesz zrozumieć ogólnie zagmatwaną i technokratyczną dokumentację. Dzisiaj przeprowadziłem kilka eksperymentów i myślę, że znalazłem najprostsze rozwiązania dla każdego zaplecza, aby móc drukować za pomocą matplotlib w systemie Windows i przy użyciu Py3.8.5 (bez wbudowanego Qt). Oto moje ustalenia:
#-------------------------------------- # 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]
Oto linki do wszystkich tych PyPi lub repozytoriów:
[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
Jednak, co było bardzo zaskakujące, biorąc pod uwagę ogromną ilość dokumentacji dotyczącej używania
Tcl/Tk
itkinter
pakietów dla Pythona, nie byłem w stanie go zainstalować ani znaleźć żadnych przydatnych instrukcji, jak zaimportować bibliotekę DLL do Pythona. (W przypadku Linuksa jest to trywialne, ponieważ po prostu używasz menedżera pakietów systemu operacyjnegoapt-get install <tk-what-not>
, ale ta opcja nie jest dostępna dla systemu Windows, ani nie ma żadnego prostego odpowiednika. Oto lista wielu różnych plików binarnych, które możesz uzyskać.[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 #
Może ktoś może mnie oświecić, jak zaimportować którekolwiek z nich do Pythona?
What backends are available and where?
Oświećmy się następującymi jednowierszowymi:
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
Zgodnie z dokumentacją: istnieją 3 sposoby konfiguracji zaplecza:
rcParams["backend"]
(domyślnie: 'agg') w pliku matplotlibrcMPLBACKEND
zmiennej środowiskowej (powłoki)matplotlib.use()
Using the backend
Wreszcie, aby użyć dostępnego zaplecza, wystarczy zrobić to:
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
źródło