
matplotlib 架構(gòu)
matplotlib 的架構(gòu)分為以下三層
- Scripting (腳本)層
- Artist (表現(xiàn))層
- Backend (后端)層
它們之間的訪問關(guān)系是:
Scripting 訪問 Artist, Artist 訪問 Backend
各層級的作用
Backend 為最底層,即 matplotlib API 層,包含的元素有:
- FigureCanvas 對象實(shí)現(xiàn)了繪圖區(qū)的概論
- Renderer 對象在FigureCanvas 上繪圖
- Event 對象處理用戶輸入(鍵盤和鼠標(biāo)事件)
Artist 層擁有許多可視化元素,即標(biāo)題、軸標(biāo)簽、刻度等元素。Aitist 類分為兩種:原始(primitive)和復(fù)合(composite),即單元素的使用和多元素組合使用。
- Figure
- Axes
- Text
- Y-axis
- Y-ticks
- Y-label
- X-axis
- X-label
- X-ticks
- Line2D
- Axes
Artist 最上層是 Figure 層,表示圖形概念; Axes 在 Figure 上面,表示軸的作圖的內(nèi)容(即軸對象),每個(gè)維度會有一個(gè) Axes 對象;Axis 用來展示 Axes 上的數(shù)值(即刻度與刻度值),刻度的位置用 Locator 對象管理,刻度的標(biāo)簽的格式用 Formatter 對象調(diào)整。
Scripting 層包含 pylab 和 pylot 模塊,這將是重點(diǎn)學(xué)習(xí)的內(nèi)容,不過 pylab 暫不介紹
使用 pylot 生成一幅簡單的交互式圖像
'''首先導(dǎo)入pylot模塊'''
import matplotlib.pyplot as plt
'''調(diào)用plot()函數(shù)'''
plt.plot([1, 2, 3, 4])
'''調(diào)用show()函數(shù),顯示圖像'''
plt.show()

注意,如果是在QtConsole環(huán)境中時(shí),不用show()函數(shù)也可以顯示圖像
解析:
plot()函數(shù)需要知道x、y值的對應(yīng)關(guān)系,才能畫出圖像,上例中只傳入了一個(gè)列表,plot會將其當(dāng)作y的值,而x的值會默認(rèn)取0、1、2……的遞增數(shù)值與y值進(jìn)行對應(yīng),便形成了上圖的結(jié)果
下面,我們?yōu)?code>plot()分別指定x與y的值
plt.plot([1, 2, 3, 4, 5], [2, 9, 6, 4 , 7])
plt.show()

線條的默認(rèn)顏色是藍(lán)色的,可以嘗試改變它的顏色:
plt.plot([1, 2, 3, 4, 5], [2, 9, 6, 4 , 7], 'red')
plt.show()

好了,從上面的例子,已經(jīng)摸索出:第一個(gè)參數(shù)的列表表示x軸的數(shù)據(jù),第二個(gè)參數(shù)的列表表示y軸的數(shù)據(jù),第三個(gè)參數(shù)表示的是線條的顏色可。
另外,觀察到,x/y軸的刻度值是隨著數(shù)據(jù)自動匹配的,那如何手動匹配呢?可使用axis()函數(shù)來設(shè)定刻度的范圍:
plt.axis([0,8,0,10])
plt.plot([1, 2, 3, 4, 5], [2, 9, 6, 4 , 7], 'red')
plt.show()

可以看到,線條的形狀不變,但它所在的位置發(fā)生了變化,因?yàn)榭潭茸兞耍?code>axis()中的參數(shù)是個(gè)列表,列表[xmin, xmax, ymin, ymax]中的元素分別指定x軸的最小與最大值,y軸的最小與最大值。
順便說一下,title()函數(shù)可以為圖表添加標(biāo)題:
plt.axis([0,8,0,10])
plt.title('我的標(biāo)題')
plt.plot([1, 2, 3, 4, 5], [2, 9, 6, 4 , 7], 'red')
plt.show()

x和y軸數(shù)據(jù)雖然可以傳入列表,實(shí)際上在使用的時(shí)候會被轉(zhuǎn)換成numpy類型,所以可以直接傳入numpy類型作參數(shù),效率會更高。
另外再提一下,第三個(gè)參數(shù)除了可以指定顏色外,還可以指定畫圖像的形狀:
plt.axis([0,8,0,10])
plt.plot([1, 2, 3, 4, 5], [2, 9, 6, 4 , 7], 'ro')
plt.show()

'''導(dǎo)入math和numpy'''
import math
import numpy as np
'''生成0到2.5,間隔為0.1的數(shù)列'''
t = np.arange(0,2.5,0.1)
'''
math.pi指圓周率,這里將t中的所有元素乘以圓周率后,
依次作用于math.sin函數(shù)上,并返回一個(gè)可迭代序列
'''
y1 = list(map(math.sin,math.pi*t))
'''用法同上,只是將t乘以圓周率的值再加上math.pi/4的值,表示偏移量'''
y2 = list(map(math.sin,math.pi*t+math.pi/4))
'''用法同上,這里的偏移量是負(fù)數(shù)'''
y3 = list(map(math.sin,math.pi*t-math.pi/4))
'''畫圖'''
plt.plot(t,y1,'b*',t,y2,'g^',t,y3,'ys')
plt.show()

解析:
來看一下plot()的使用語法
Signature: plt.plot(*args, **kwargs)
Docstring:
Plot y versus x as lines and/or markers.
Call signatures::
plot([x], y, [fmt], data=None, **kwargs)
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
The coordinates of the points or line nodes are given by *x*, *y*.
其中plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)指出了可以連續(xù)使用多個(gè)x/y/fmt參數(shù)來同時(shí)畫多個(gè)圖形。
根據(jù)上例,可得知,fmt參數(shù),第一個(gè)字母表示顏色,字母后面的字符表示形狀,b*則表示的是藍(lán)色的星號,g^表示的則是綠色的三角,ys表示的是黃色的方塊。
再看個(gè)例子:
plt.plot(t,y1,'b--',t,y2,'r.',t,y3,'g+')
plt.show()

是不是很奇妙O(∩_∩)O哈哈~
了解 plot() 的參數(shù)
在上面的例子里,已經(jīng)看到plot()的語法是plt.plot(*args, **kwargs),可見,可以傳入列表與字典類型的參數(shù),列表類型的參數(shù)已經(jīng)在上面的各例中使用過了,那字典類型的參數(shù)如何使用呢?
字典類型的參數(shù)又叫關(guān)鍵字參數(shù),又稱kwargs,在plot()的使用中,關(guān)鍵字參數(shù)一般用來設(shè)置相關(guān)屬性,比如下面的例子中,設(shè)置線條的粗細(xì):
plt.plot(t,y1,linewidth=5.0)
plt.show()

linewidth相關(guān)于key,5.0則是value,能過這種一一對應(yīng)關(guān)系,來指定線條的粗細(xì)。
處理多個(gè) Figure 和 Axes 對象
這里想表達(dá)的是,在一個(gè)圖形 Figure 中,使用多個(gè)圖例 Axes;那如何實(shí)現(xiàn)呢?先看下例子,然后再作解析:
t = np.arange(0,5,0.1)
y1 = np.sin(2*np.pi*t)
y2 = np.sin(2*np.pi*t)
plt.subplot(211)
plt.plot(t,y1,'b-')
plt.subplot(212)
plt.plot(t,y2,'r*')
plt.show()

解析:
首先生成了x與y的數(shù)據(jù)
t = np.arange(0,5,0.1)
y1 = np.sin(2*np.pi*t)
y2 = np.sin(2*np.pi*t)
subplot()函數(shù),可以將圖形分為不同的繪圖區(qū)域,參數(shù)中的211指的是:按垂直方向分成2份,按水平方向分成1份,當(dāng)前可被控制的是第1個(gè)區(qū)域
plt.subplot(211)
然后對第一個(gè)區(qū)域進(jìn)行繪圖
plt.plot(t,y1,'b-')
如果想在第二個(gè)圖上進(jìn)行繪圖,需要將控制指令切換到第二個(gè)區(qū)域,使用subplot(212)來指定第三個(gè)參數(shù)值為2,即控制第二個(gè)區(qū)域
plt.subplot(212)
最后,在第二個(gè)區(qū)域上繪圖,并顯示所有
plt.plot(t,y2,'r*')
plt.show()
接下來再看一下如何將圖分成左右兩個(gè)區(qū)域:
t = np.arange(0,5,0.1)
y1 = np.sin(2*np.pi*t)
y2 = np.sin(2*np.pi*t)
plt.subplot(121)
plt.plot(t,y1,'b-')
plt.subplot(122)
plt.plot(t,y2,'r*')
plt.show()
