mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

matplotlib面向物件繪圖快感初體驗

本篇將:

引入mpl面向物件繪圖的幾個重要概念和物件;

採用純面向物件的繪圖方式繪製一個基本圖形;

與函式式繪圖做一些簡單比較;

自定義一個figure類,實現圖形基本格式的統一定製;

提供一個有更多物件的示例供有興趣者研究。

matplotlib設計了兩種繪圖模式:

pyplot模組的函式式繪圖

object-oriented的面向物件,簡稱OO。

什麼是mpl的物件?

簡單地說,mpl對我們繪圖中要用到的一些元素進行了分級、分組、歸類,這些元素就是物件。

比如,最基本的圖形物件——-Figure,座標系物件——-Axes,座標軸物件Axis,Axis上的XTick YTick(刻度)物件。

mpl提供了一些python類,class,用來抽象、描述、定製這些物件。

小提示:

根據Python命名規範,Class名用首字母大寫的單詞命名,如果需要多個單詞,接著寫,首字母大寫以區分單詞,如MyFigA;變數名全用小寫字母的單詞,單詞之間用短下劃線連線。比如,XTick就是一個Class類名,而如axes_a這樣的應該是一個變數名。我們在命名時也應該遵循這個規範。

約定

有些物件、概念,翻譯後反而不便於理解,所以我們約定如下:

Figure,

圖形類Class;

Axes,

是Axis的複數形式,意即2個以上的座標軸,有很多地方也譯為座標軸,這容易混淆。在基礎篇中,我們只討論2D平面座標,Axes就是

平面座標系

。而Axis則是這個座標系中的兩條軸線之一,用x, y表示。Axes是座標系,它實際代表一個矩形區域。

Canvas,

畫布,繪圖時我們都需要附加一個畫布物件,Photoshop也是如此,至於為什麼要這麼一個畫布物件,我們後面再討論,我們先記住,Figure必須附加到一個Canvas。

你暫時不需要完全理解每行程式碼,你只需要照著體驗一下純面向物件繪圖和函式式繪圖的區別。

建立一個空白的Figure

mpl提供了一個Figure類,例項化這個類即可建立一個figure例項。Figure類的呼叫方法如下:

class matplotlib。figure。Figure(figsize=None, dpi=None, facecolor=None, edgecolor=None, linewidth=0。0, frameon=None, subplotpars=None, tight_layout=None, constrained_layout=None)

你甚至不需要提供任何引數,mpl會使用預設引數建立一個圖形。

啟動jupyter lab,新建一個ipynb檔案,輸入如下程式碼:

from matplotlib。backends。backend_agg import FigureCanvasAggfrom matplotlib。figure import Figurefrom matplotlib。axes import Axesimport numpy as npfrom numpy import math#例項化Figure類,並將例項賦給變數figfig =Figure()#例項化一個FigureCanvasAgg畫布#並附加到前面建立的Figure例項fig上canvas = FigureCanvasAgg(fig)#將圖形渲染到快取s, (width, height) = canvas。print_to_buffer() from PIL import Image #呼叫PIL庫將快取中的資料渲染為影象im = Image。frombytes(“RGBA”, (width, height), s)#呼叫系統圖片檢視器檢視影象# 在本例中Figuer中還什麼都沒有僅是一個空白區域。im。show() #如果需要,你還可以將繪圖儲存為磁碟檔案canvas。print_figure(‘tth001。jpg’)

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

執行它,會自動開啟系統預設的圖片檢視器,顯示生成的圖片。因為現在圖上還什麼都沒有,所以僅一塊空白的區域。

但這恰是Figure物件的本質,

它就是一個頂級容器,一塊矩形區域,用來放置後面的元素。

建立一個Axes

mpl提供了一個Axes類用於建立座標系。

class matplotlib。axes。Axes(fig, rect, facecolor=None, frameon=True, sharex=None, sharey=None, label=‘’, xscale=None, yscale=None, **kwargs)

Axes首先也是一個矩形區域,它是Figure的一個子區域。一個Figure可以劃分為多個Axes子區域。

Axes至少需要兩個引數 fig, rect。fig是軸所在的figure,rect是定義矩形區域的左、底、寬、高的浮點數列表,如[0。1,0。1,0。5,0。5]。它的單位是相對於figure這個矩形區域的分數,用0-1之間的小數表示。

在上面的程式碼中新增如下程式碼:

rect = [0。1,0。1,0。8,0。8]ax = Axes(fig,rect)fig。add_axes(ax)

完整程式碼如下:

from matplotlib。backends。backend_agg import FigureCanvasAggfrom matplotlib。figure import Figurefrom matplotlib。axes import Axesimport numpy as npfrom numpy import math#例項化Figure類,並將例項賦給變數figfig =Figure()#例項化一個FigureCanvasAgg畫布#並附加到前面建立的Figure例項fig上canvas = FigureCanvasAgg(fig)#建立一個axes物件rect = [0。1,0。1,0。8,0。8]ax = Axes(fig,rect)fig。add_axes(ax)s, (width, height) = canvas。print_to_buffer() from PIL import Image #呼叫PIL庫將快取中的資料渲染為影象im = Image。frombytes(“RGBA”, (width, height), s)#呼叫系統圖片檢視器檢視影象# 在本例中Figuer中還什麼都沒有僅是一個空白區域。im。show() #如果需要,你還可以將繪圖儲存為磁碟檔案#canvas。print_figure(‘tth001。jpg’)

這時我們就能看到,在前面的圖形中有了一個座標系。

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

在這個Figure中我們看不出來figure和Axes的位置關係。

pyplot函式繪圖很簡單,但很模糊

我們使用函式式繪圖繪製一個類似的圖形,只需要3行程式碼。

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

這時,有人就要問了:你為什麼要舍簡求繁?

而我要反回你幾個問題:

你知道figure必須附加到一個canvas上嗎?

你在哪裡建立canvas的?

你在哪裡繪製的Axes?

如果你要修改這個Axes,讓它的右邊留出更多的空白,你怎麼做?

如果Figure中有兩個Axes,如ax_a,ax_b,你如何向指定的Aexs新增繪圖元素?

等等,這樣的問題很多。

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

上圖的原始碼請訪問”Python草堂群“457079928下載。

這個figure中有兩個axes,要控制不同軸的格式及其中圖形元素的格式,不使用面向物件繪圖,將深受物件定位和選擇的困擾。

透過自定義類統一你的繪圖風格

我們寫論文、書籍時,一般應該保證插入圖表基本風格的一致,如配色、大小、佈局等的一致。

比如我準備在本系列文章中,經常採用一個圖形左右兩個Axes,以便對比引數不同設定的效果,同時為了便於理解不同座標系統、不同區域,我明確標出figure的邊框和底色。

為了避免做一些重複設定,簡化面向物件繪圖的程式碼,我將定義一個Figure子類,定製好基本風格,後面直接引入這個子類即可保證風格的統一,又能簡化程式碼。

下面的程式碼定義了一個名為”MyFigA()“的子類,它繼承了mpl的Figure類,但重設了尺寸、邊框、顏色等屬性。

class MyFigA(Figure): #設定一些顏色值 ax_fca = (249/256,244/256,206/256) ax_fcb = (138/256,176/256,209/256) pl_cb = (8/256,89/256,156/256) pl_cr = (239/256,8/256,8/256) def __init__(self, figsize=(9。6,4。8), #在這裡修改父類引數的預設值 dpi=100, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=10。0, frameon=True, subplotpars=None, tight_layout=None, constrained_layout=None, ): # 子類呼叫父類的方法 super(MyFigA, self)。__init__(figsize, dpi,facecolor,edgecolor, linewidth,frameon,subplotpars, tight_layout,constrained_layout)

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

tth。py檔案

後面,我們只要引用這個類,即可重複使用這個所示的Figure模板:

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

使用自定義類

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

這就像一個figure模板

一個完成更多工的純面向物件繪圖的示例

向上面Figure模板新增更多的元素,這些都是完全面向物件的方法實現的。

新增兩個Axes;

為每個Axes添加了兩個三角函式曲線;

新增風格;

對兩個Axes及其元素賦予不同的顏色,以示區別。

最重要的,就像在現實中繪畫一樣,在哪個區域繪製什麼?要向不同的區域新增什麼樣的藝術(artists)元素,自己的頭腦中都非常清晰。

程式碼如下:

import tthfrom matplotlib。axes import Axesfrom numpy import mathfig = MyFigA()canvas = FigureCanvasAgg(fig)ax_a = Axes(fig, [0。08,0。08,0。4,0。85], facecolor=fig。ax_fca)ax_b = Axes(fig, [0。55, 0。08,0。4,0。85], facecolor=fig。ax_fcb) fig。add_axes(ax_a)fig。add_axes(ax_b)x = np。arange(0, 2*math。pi, 0。001)y = np。sin(x)ax_a。plot(x, y, color=fig。pl_cr)ax_b。plot(x, y, color=fig。pl_cb) ax_a。plot(x, np。cos(x), color=‘g’)ax_b。plot(x, np。cos(x), color=‘r’) ax_a。grid(b=True,lw=2)ax_b。grid(b=True,lw=2)s, (width, height) = canvas。print_to_buffer() from PIL import Image #呼叫PILim = Image。frombytes(”RGBA“, (width, height), s)im。show()

mpl學習筆記基礎篇001-matplotlib面向物件繪圖快感初體驗

原始碼請訪問”Python草堂“群457079928下載。

總結:

像現實中繪畫一樣,自主控制matplotlib的繪圖,讓我們非常清楚圖形的每個子區域、每個元素,誰是誰,我正在操控誰!

是不是比函式繪圖一筆糊塗賬要有快感呢?

下一篇,我們將解析一下matplotlib的物件結構,然後開始重點討論Figure物件。當你透徹地理解了Fgiure,當你看Figure就像庖丁看一頭牛一樣時,你的matplotlib就會不知不覺地上升到一個全新的境界。

關注“Python草堂”,輕鬆閱讀下一篇。