撰寫後端程式 -- pyplot 介面#

此頁面假設您已大致了解 後端 頁面中的資訊,並且主要是作為第三方後端實作者的參考。它也只處理後端與 pyplot 之間的互動,而不是渲染部分,後者在 backend_template 中說明。

有兩種 API 可用於定義後端:新的基於畫布的 API(在 Matplotlib 3.6 中引入),以及較舊的基於函式的 API。新的 API 更易於實作,因為許多方法可以從「父後端」繼承。如果 Matplotlib < 3.6 的回溯相容性不是問題,建議使用新的 API。然而,舊的 API 仍然支援。

從根本上來說,後端模組需要向 pyplot 提供資訊,以便

  1. pyplot.figure() 可以建立新的 Figure 實例,並將其與後端提供的畫布類別的實例相關聯,該實例本身託管在後端提供的管理器類別的實例中。

  2. pyplot.show() 可以顯示所有圖表並啟動 GUI 事件迴圈(如果有的話)。

為此,後端模組必須定義 backend_module.FigureCanvas,它是 FigureCanvasBase 的子類別。在基於畫布的 API 中,這是後端模組的唯一嚴格要求。基於函式的 API 還需要定義許多模組層級的函式。

基於畫布的 API (Matplotlib >= 3.6)#

  1. 建立圖表pyplot.figure() 會呼叫 figure = Figure(); FigureCanvas.new_manager(figure, num)new_manager 是一個類別方法)來實例化畫布和管理器,並設定 figure.canvasfigure.canvas.manager 屬性。圖表取消封裝會使用相同的方法,但會將新實例化的 Figure() 取代為取消封裝的圖表。

    互動式後端應該透過將 FigureCanvas.manager_class 屬性設定為所需的管理器類別,來自訂 new_manager 的效果,並額外(如果畫布無法在管理器之前建立,就像 wx 後端的情況一樣)覆寫 FigureManager.create_with_canvas 類別方法。(非互動式後端通常可以使用簡單的 FigureManagerBase,因此可以跳過此步驟。)

    在新的圖表透過 pyplot 註冊(透過 pyplot.figure() 或透過取消封裝)後,如果在互動模式下,pyplot 會呼叫其畫布的 draw_idle() 方法,該方法可以根據需要覆寫。

  2. 顯示圖表pyplot.show() 會呼叫 FigureCanvas.manager_class.pyplot_show()(一個類別方法),傳遞任何參數,以啟動主事件迴圈。

    預設情況下,pyplot_show() 會檢查是否有任何 managerspyplot 註冊(如果沒有則提前結束),在所有此類管理器上呼叫 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#

  1. 建立圖表pyplot.figure() 會呼叫 new_figure_manager(num, *args, **kwargs)(它也會負責建立新的圖表作為 Figure(*args, **kwargs));取消封裝會呼叫 new_figure_manager_given_figure(num, figure)

    此外,在互動模式下,可以透過提供模組層級的 draw_if_interactive() 函式來自訂新註冊圖表的第一次繪製。(在新的基於畫布的 API 中,不再考慮此函式。)

  2. 顯示圖表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 來使用。例如 mplcairomodule://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() 時。