วิธีเปลี่ยนแบ็กเอนด์ใน matplotlib / Python


90

ฉันกำลังดิ้นรนกับปัญหาต่อไปนี้ ฉันต้องการสร้างรายงานที่ประกอบด้วยชุดแผนภูมิ แผนภูมิเหล่านี้ทั้งหมดยกเว้นแผนภูมิเดียวสร้างโดยใช้แบ็กเอนด์เริ่มต้นของ Matplotlib (TkAgg) ต้องสร้างแผนภูมิหนึ่งรายการโดยใช้แบ็กเอนด์ไคโรเหตุผลคือฉันกำลังพล็อตกราฟ igraph และสามารถพล็อตได้โดยใช้ไคโร

ปัญหาคือฉันไม่สามารถเปลี่ยนแบ็กเอนด์ได้ทันทีตัวอย่างเช่นสิ่งต่อไปนี้ใช้ไม่ได้:
matplotlib.pyplot.switch_backend('cairo.png') (ฉันรู้ว่าฟังก์ชัน switch_backend กำลังทดลอง)

และฉันได้พยายามยังmatplotlib.use("cairo.png")แต่นี้นำไปสู่การแก้ปัญหาการนำเข้าเป็นคำสั่งที่ควรจะมาก่อนนำเข้าmatplotlib.use("cairo.png") matplotlib.pyplotแต่ฉันต้องการแบ็กเอนด์สองแบบที่แตกต่างกันตลอดช่วงชีวิตของสคริปต์

คำถามของฉันคือใครบางคนมีข้อมูลโค้ดที่แสดงวิธีเปลี่ยนแบ็กเอนด์ใน Matplotlib หรือไม่

ขอบคุณมาก!

อัปเดต: ฉันได้เขียนตัวอย่างข้อมูลที่โหลด matplotlib แสดงแบ็กเอนด์เริ่มต้นยกเลิกการโหลด matplotlib โหลดซ้ำและเปลี่ยนแบ็กเอนด์:

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

แต่นี่เป็นวิธีที่ทำได้จริงหรือ

อัปเดต 2: เมื่อวานฉันมีอาการสมองหยุดทำงานอย่างรุนแรง ... วิธีแก้ปัญหาที่ง่ายและชัดเจนที่สุดคือใช้แบ็กเอนด์ของไคโรสำหรับแผนภูมิทั้งหมดและไม่ต้องสลับแบ็กเอนด์เลย :)

อัปเดต 3: จริงๆแล้วมันยังคงเป็นปัญหาอยู่ดังนั้นใครก็ตามที่รู้วิธีสลับแบ็กเอนด์ matplotlib แบบไดนามิก .... โปรดโพสต์คำตอบของคุณ


มีpyplot.switch_backends(). อาจไม่ได้ผลในกรณีของคุณ
jfs

คำตอบ:


60

หกปีต่อมาและฉันก็เจอปัญหาที่คล้ายกันเมื่อพยายามตัดสินใจว่าbackendจะใช้ตัวไหนได้บ้าง
หมายเหตุดูคำเตือน - ด้านล่าง

ข้อมูลโค้ดนี้ใช้ได้ดีสำหรับฉัน:

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

ในขณะที่คุณสามารถอนุมานได้การแลกเปลี่ยนbackendเป็นเรื่องง่ายเหมือนการนำเข้าmatplotlib.pyplotใหม่หลังจากบังคับให้ใหม่backend

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

Switched to: WXAgg

สำหรับผู้ที่ยังประสบปัญหารหัสนี้จะพิมพ์ออกมา:
รายการแบ็กเอนด์ Non Gui;
รายชื่อแบ็กเอนด์ Gui;
จากนั้นลองใช้แบ็กเอนด์ Gui แต่ละตัวเพื่อดูว่ามีอยู่และทำงานได้หรือไม่

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

คำเตือน: การเปลี่ยนแปลงใน matplotlib ตั้งแต่เวอร์ชัน 3.3.0

  • พารามิเตอร์แรกของ matplotlib.use ถูกเปลี่ยนชื่อจาก arg เป็นแบ็กเอนด์ (เกี่ยวข้องเฉพาะเมื่อคุณส่งผ่านคีย์เวิร์ด)
  • พารามิเตอร์คำเตือนของ matplotlib.use ถูกลบออก ความล้มเหลวในการสลับแบ็กเอนด์ในขณะนี้จะทำให้ ImportError เพิ่มขึ้นเสมอหากตั้งค่าบังคับ จับข้อผิดพลาดนั้นหากจำเป็น
  • พารามิเตอร์ทั้งหมดของ matplotlib.use ยกเว้นพารามิเตอร์แรกเป็นคีย์เวิร์ดเท่านั้น

ขอบคุณ! สิ่งนี้ช่วยให้ฉันพบส่วนหลังที่เหมาะสมสำหรับตัวอย่างนี้: stackoverflow.com/questions/11874767/…
James Nelson

Rolf of Saxony, LOL มีประโยชน์มากฉันยังคงได้รับคำตอบใน Ubuntu และ Android โพสต์เมื่อเกือบทศวรรษที่แล้ว
James Nelson

warn=Falseอาร์กิวเมนต์ไม่สามารถใช้ได้อีก
not2qubit

@ not2qubit สังเกต - ขอบคุณ เพิ่มคำเตือน
Rolf of Saxony

37

มีคุณลักษณะ "ทดลอง":

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

นำมาจากmatplotlib doc

เปลี่ยนแบ็กเอนด์เริ่มต้นเป็นแบ็กเอนด์ใหม่ คุณลักษณะนี้อยู่ ระหว่างการทดลองและคาดว่าจะใช้งานได้โดยเปลี่ยนไปใช้แบ็กเอนด์รูปภาพเท่านั้น เช่นหากคุณมีสคริปต์ PostScript จำนวนมากที่คุณต้องการเรียกใช้จากเซสชัน ipython แบบโต้ตอบคุณอาจต้องการเปลี่ยนไปใช้แบ็กเอนด์ PS ก่อนที่จะเรียกใช้เพื่อหลีกเลี่ยงการมีป๊อปอัปหน้าต่าง GUI จำนวนมาก หากคุณพยายามสลับแบบโต้ตอบจากแบ็กเอนด์ GUI หนึ่งไปยังอีกแบ็กเอนด์คุณจะระเบิด การเรียกใช้คำสั่งนี้จะปิดหน้าต่างที่เปิดอยู่ทั้งหมด


สตริงแบ็กเอนด์ "newbackend" ที่ไม่รู้จัก ฉันควรทำอย่างไรดี?
TSR

5
@TSR แทนที่ 'newbackend' ด้วยแบ็กเอนด์ GUI เช่น 'Qt4Agg'
YashTD

14

ทำไมไม่ใช้แค่reloadฟังก์ชันimportlib.reloadในตัว( ใน Python 3)

import matplotlib
matplotlib.use('agg')

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

เช่นเดียวกับในคุณไม่สามารถโหลด matplotlib และ matplotlib.pyplot ใหม่ได้? หรือคุณแค่บอกว่าการตัดโค้ดของฉันไม่สมบูรณ์?
fredbaba

อืม. อาจเป็นมุมมองของ IPython จริงๆ ดูเหมือนว่าจะทำงานได้ดีในคอนโซลปกติ
Mad Physicist

1
ฉันคิดว่านี่เป็นตัวอย่างที่แสดงให้เห็นว่ามันไม่ได้ผล: python -c "import matplotlib.pyplot as plt; import matplotlib; from importlib import reload; matplotlib = reload(matplotlib); matplotlib.use('Agg')"ใช่มั้ย?
Lukas

6

ดังนั้นฉันจึงไม่แน่ใจว่านี่คือสิ่งที่คุณกำลังมองหาหรือไม่

คุณสามารถเปลี่ยนแบ็กเอนด์ของคุณผ่านไฟล์ matplotlibrc ซึ่งมีการกำหนดค่าบางอย่างสำหรับ matplotlib ของคุณ

ในสคริปต์ของคุณคุณสามารถใส่:

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

หรืออะไรทำนองนั้นเพื่อสลับระหว่างแบ็กเอนด์


2
แน่นอนคุณสามารถระบุแบ็กเอนด์ในพจนานุกรม rcParams ของคุณได้ แต่นั่นไม่ได้ช่วยแก้ปัญหาในการเปลี่ยนจากแบ็กเอนด์หนึ่งไปยังอีกแบ็กเอนด์
DrDee

คุณยังสามารถตั้งค่าแบ็กเอนด์เริ่มต้นในไฟล์ config ซึ่ง matplotlib หยิบขึ้นมาได้:~/.config/matplotlib/matplotlibrc
scrutari

4

ในกรณีของฉัน (Windows 10 + python 3.7) คำตอบแรกโดย @Rolf of Saxony ทำงานได้ไม่ดีนัก แทนที่จะลองใช้สภาพแวดล้อมที่มีอยู่ทั้งหมดและกำหนดค่าอย่างใดอย่างหนึ่งในตอนเริ่มต้นเช่นหลังจากนั้น

    import matplotlib

ฉันต้องเปลี่ยนสภาพแวดล้อมจาก "Agg" เป็น "TkAgg" โดยใช้ไฟล์

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

ก่อนโค้ดที่ฉันพล็อตจริงกล่าวคือ

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

2

หากต้องการเปลี่ยนแบ็กเอนด์อย่างถาวรคุณสามารถใช้สิ่งนี้:

  1. อันดับแรกค้นหาmatplotlibrcไฟล์:

    import matplotlib
    
    matplotlib.matplotlib_fname()
    # '/Users/serafeim/.matplotlib/matplotlibrc'
    
  2. เปิดเทอร์มินัลแล้วทำ:

    cd /Users/serafeim/.matplotlib/
    ls
    
  3. แก้ไขไฟล์ (หากไม่มีอยู่ให้ใช้คำสั่งนี้: touch matplotlibเพื่อสร้าง):

    vim matplotlibrc
    
  4. เพิ่มบรรทัดนี้และบันทึก:

    backend: TkAgg
    

1

นอกจากนี้คุณยังสามารถมีกระบวนการหลามทำให้แตกต่างกันที่พล็อตอาจจะเป็นด้วยความช่วยเหลือของดองหรือjoblib


0

หากคุณใช้คอนโซล IPython (รวมถึงภายใน Spyder) คุณสามารถใช้คำสั่งเวทมนตร์ในตัวเพื่อสลับแบ็กเอนด์ได้อย่างรวดเร็วเช่น:

%matplotlib qt

รับรายการแบ็กเอนด์ที่มีเพื่อใช้กับคำสั่ง:

%matplotlib --list

แบ็กเอนด์ matplotlib ที่ใช้ได้: ['tk', 'gtk', 'gtk3', 'wx', 'qt4', 'qt5', 'qt', 'osx', 'nbagg', 'notebook', 'agg', ' svg ',' pdf ',' ps ',' inline ',' ipympl ',' widget ']


0

Extra Info

แม้ว่าทุกคนจะแสดงแบ็คเอนด์ที่ตัวเองชื่นชอบ แต่ก็ค่อนข้างยุ่งในการคิดว่าคุณต้องติดตั้งอะไรและข้อกำหนดคืออะไร อย่างน้อยที่สุดเมื่อคุณพยายามทำความเข้าใจเอกสารที่สับสนและเป็นเทคโนโลยีโดยทั่วไป วันนี้ฉันได้ทำการทดลองหลายครั้งและคิดว่าฉันได้พบวิธีแก้ปัญหาที่ง่ายที่สุดสำหรับแบ็คเอนด์แต่ละตัวเพื่อให้สามารถพล็อตด้วยmatplotlibใน Windows และใช้ Py3.8.5 (โดยไม่มี Qt ในตัว) นี่คือสิ่งที่ฉันค้นพบ:

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

นี่คือลิงค์ไปยัง PyPi หรือ 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

อย่างไรก็ตามและน่าแปลกใจมากที่ได้รับเอกสารสำหรับการใช้งานTcl/Tkและtkinterแพ็คเกจสำหรับ python จำนวนมากฉันไม่สามารถติดตั้งได้และไม่พบคำแนะนำที่เป็นประโยชน์เกี่ยวกับวิธีการนำเข้า DLL ไปยัง python (สำหรับลินุกซ์นี่เป็นเรื่องเล็กน้อยเมื่อคุณใช้ตัวจัดการแพ็คเกจ OS apt-get install <tk-what-not>แต่ตัวเลือกนี้ไม่สามารถใช้ได้กับ windows และไม่มีอะนาล็อกง่ายๆใด ๆ นี่คือรายการของไบนารีจำนวนมากและหลากหลายที่คุณจะได้รับ

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

อาจมีใครบางคนสามารถให้ความกระจ่างแก่ฉันได้ว่าจะนำสิ่งเหล่านี้เข้าสู่ python ได้อย่างไร?


What backends are available and where?

มาสอนตัวเองด้วยหนึ่งสมุทรต่อไปนี้:

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

ตามเอกสารระบุ: มี 3 วิธีในการกำหนดค่าแบ็กเอนด์ของคุณ:

  1. การตั้งค่าrcParams["backend"]พารามิเตอร์ (default: 'agg') ในmatplotlibrcของคุณไฟล์
  2. การตั้งค่า MPLBACKENDตัวแปรสภาพแวดล้อม (เชลล์)
  3. การใช้ฟังก์ชัน matplotlib.use()

Using the backend

สุดท้ายการใช้แบ็กเอนด์ที่มีอยู่ของคุณเป็นเพียงเรื่องของการทำสิ่งนี้:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.