撰寫後端程式 -- pyplot 介面#
此頁面假設您已大致了解 後端 頁面中的資訊,並且主要是作為第三方後端實作者的參考。它也只處理後端與 pyplot
之間的互動,而不是渲染部分,後者在 backend_template
中說明。
有兩種 API 可用於定義後端:新的基於畫布的 API(在 Matplotlib 3.6 中引入),以及較舊的基於函式的 API。新的 API 更易於實作,因為許多方法可以從「父後端」繼承。如果 Matplotlib < 3.6 的回溯相容性不是問題,建議使用新的 API。然而,舊的 API 仍然支援。
從根本上來說,後端模組需要向 pyplot
提供資訊,以便
pyplot.figure()
可以建立新的Figure
實例,並將其與後端提供的畫布類別的實例相關聯,該實例本身託管在後端提供的管理器類別的實例中。pyplot.show()
可以顯示所有圖表並啟動 GUI 事件迴圈(如果有的話)。
為此,後端模組必須定義 backend_module.FigureCanvas
,它是 FigureCanvasBase
的子類別。在基於畫布的 API 中,這是後端模組的唯一嚴格要求。基於函式的 API 還需要定義許多模組層級的函式。
基於畫布的 API (Matplotlib >= 3.6)#
建立圖表:
pyplot.figure()
會呼叫figure = Figure(); FigureCanvas.new_manager(figure, num)
(new_manager
是一個類別方法)來實例化畫布和管理器,並設定figure.canvas
和figure.canvas.manager
屬性。圖表取消封裝會使用相同的方法,但會將新實例化的Figure()
取代為取消封裝的圖表。互動式後端應該透過將
FigureCanvas.manager_class
屬性設定為所需的管理器類別,來自訂new_manager
的效果,並額外(如果畫布無法在管理器之前建立,就像 wx 後端的情況一樣)覆寫FigureManager.create_with_canvas
類別方法。(非互動式後端通常可以使用簡單的FigureManagerBase
,因此可以跳過此步驟。)在新的圖表透過
pyplot
註冊(透過pyplot.figure()
或透過取消封裝)後,如果在互動模式下,pyplot
會呼叫其畫布的draw_idle()
方法,該方法可以根據需要覆寫。顯示圖表:
pyplot.show()
會呼叫FigureCanvas.manager_class.pyplot_show()
(一個類別方法),傳遞任何參數,以啟動主事件迴圈。預設情況下,
pyplot_show()
會檢查是否有任何managers
向pyplot
註冊(如果沒有則提前結束),在所有此類管理器上呼叫manager.show()
,然後,如果呼叫時帶有block=True
(或預設值block=None
並且不在 IPython 的 pylab 模式下且不在互動模式下),則會呼叫FigureCanvas.manager_class.start_main_loop()
(一個類別方法)以啟動主事件迴圈。因此,互動式後端應該相應地覆寫FigureCanvas.manager_class.start_main_loop
類別方法(或者,它們也可以直接覆寫FigureCanvas.manager_class.pyplot_show
)。
基於函式的 API#
建立圖表:
pyplot.figure()
會呼叫new_figure_manager(num, *args, **kwargs)
(它也會負責建立新的圖表作為Figure(*args, **kwargs)
);取消封裝會呼叫new_figure_manager_given_figure(num, figure)
。此外,在互動模式下,可以透過提供模組層級的
draw_if_interactive()
函式來自訂新註冊圖表的第一次繪製。(在新的基於畫布的 API 中,不再考慮此函式。)顯示圖表:
pyplot.show()
會呼叫模組層級的show()
函式,該函式通常是透過ShowBase
類別及其mainloop
方法產生的。
註冊後端#
為了使新的後端能夠透過 matplotlib.use()
或 IPython 的 %matplotlib
魔術指令使用,它必須與 BackendRegistry
支援的三種方式之一相容。
內建#
一個內建於 Matplotlib 的後端,其名稱和 FigureCanvas.required_interactive_framework
必須在 BackendRegistry
中硬編碼。如果後端模組不是 f"matplotlib.backends.backend_{backend_name.lower()}"
,那麼也必須在 BackendRegistry._name_to_module
中加入一個條目。
module:// 語法#
任何在獨立模組 (非內建於 Matplotlib) 中的後端,都可以透過指定模組路徑,格式為 module://some.backend.module
來使用。例如 mplcairo 的 module://mplcairo.qt
。後端的互動框架將會從其 FigureCanvas.required_interactive_framework
中取得。
進入點#
一個外部後端模組可以使用其 pyproject.toml
中的 entry point
自行註冊為後端,例如 matplotlib-inline
使用的方式。
[project.entry-points."matplotlib.backend"]
inline = "matplotlib_inline.backend_inline"
後端的互動框架將會從其 FigureCanvas.required_interactive_framework
中取得。所有的進入點會一起載入,但只有在第一次需要時才會載入,例如當一個後端名稱無法被識別為內建後端,或者當第一次呼叫 list_all()
時。