Python的matplotlib(2)
1、基礎理解
1.1 函數式繪圖
Python中的函數式編程是通過封裝對象實現的。matplotlib中的函數式調用其實也是如此。matplotlib本質上還是構建對象來構建圖像。函數式編程將構建對象的過程封裝在函數中,從而讓我們覺得很方便。
在matplotlib.pyplot中,你還可以找到下面的繪圖函數
1.2 面向對象編程
將上面的直線繪圖更改為面向對象式(OO, object-oriented)的,為此,引入兩個類: Figure和FigureCanvas。(函數式編程也調用了這些類,只是調用的過程被函數調用所遮掩。)
from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas fig = Figure() canvas = FigureCanvas(fig) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) line, = ax.plot([0,1], [0,1]) ax.set_title("a straight line (OO)") ax.set_xlabel("x value") ax.set_ylabel("y value")canvas.print_figure('demo.jpg')理解對象:
上面的例子中至少構建了四個對象: fig, canvas, ax, line。它們分別屬于Figure類,FigureCanvas類,Axes類和Line2D類。(使用obj.__class__.__name__來查詢對象所屬的類)
在matplotlib中,整個圖像為一個Figure對象。在Figure對象中可以包含一個,或者多個Axes對象。每個Axes對象都是一個擁有自己坐標系統的繪圖區域。其邏輯關系如下:
轉過頭來看直線圖。整個圖像是fig對象。我們的繪圖中只有一個坐標系區域,也就是ax。此外還有以下對象。(括號中表示對象的基本類型)
Title為標題。Axis為坐標軸,Label為坐標軸標注。Tick為刻度線,Tick Label為刻度注釋。各個對象之間有下面的對象隸屬關系:
(yaxis同樣有tick, label和tick label,沒有畫出)
盡管data是數據繪圖的關鍵部分,也就是數據本身的圖形化顯示,但是必須和xaxis, yaxis, title一起,才能真正構成一個繪圖區域axes。一個單純的,無法讀出刻度的線是沒有意義的。xaxis, yaxis, title合起來構成了數據的輔助部分(data guide)。
上面元素又包含有多種圖形元素。比如說,我們的data對象是一條線(Line2D)。title, tick label和label都是文本(Text),而tick是由短線(Line 2D)和tick label構成,xaxis由坐標軸的線和tick以及label構成,ax由xaxis, yaxis, title, data構成,ax自身又構成了fig的一部分。上面的每個對象,無論是Line2D, Text還是fig,它們都來自于一個叫做Artist的基類。
OO繪圖的原程序還有一個canvas對象。它代表了真正進行繪圖的后端(backend)。Artist只是在程序邏輯上的繪圖,它必須連接后端繪圖程序才能真正在屏幕上繪制出來(或者保存為文件)。我們可以將canvas理解為繪圖的物理(或者說硬件)實現。
在OO繪圖程序中,我們并沒有真正看到title, tick, tick label, xaxis, yaxis對象,而是使用ax.set_*的方法間接設置了這些對象。但這些對象是真實存在的,你可以從上層對象中找到其“真身”。比如,fig.axes[0].xaxis就是我們上面途中的xaxis對象。我們可以通過fig -> axes[0] (也就是ax) -> xaxis的順序找到它。因此,重復我們剛才已經說過的,一個fig就構成了一個完整的圖像。對于每個Artist類的對象,都有findobj()方法,來顯示該對象所包含的所有下層對象。
1.3 坐標
圖像坐標將一張圖的左下角視為原點,將圖像的x方向和y方向總長度都看做1。x方向的0.2就是指20%的圖像在x方向的總長,y方向0.8的長度指80%的y方向總長。(0.5, 0.5)是圖像的中點,(1, 1)指圖像的右上角。比如下面的程序,我們在使用add_axes時,傳遞的參數中,前兩個元素為axes的左下角在fig的圖像坐標上的位置,后兩個元素指axes在fig的圖像坐標上x方向和y方向的長度。fig的圖像坐標稱為Figure坐標,儲存在為fig.transFigure
(類似的,每個axes,比如ax1,有屬于自己的圖像坐標。它以ax1繪圖區域總長作為1,稱為Axes坐標。也就是ax1.transAxes。(0.5, 0.5)就表示在Axes的中心。Axes坐標和Figure坐標原理相似,只是所用的基準區域不同。)
from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasfig = plt.Figure() canvas = FigureCanvas(fig) # first axes ax1 = fig.add_axes([0.1, 0.1, 0.2, 0.2]) line, = ax1.plot([0,1], [0,1]) ax1.set_title("ax1")# second axes ax2 = fig.add_axes([0.4, 0.3, 0.4, 0.5]) sca = ax2.scatter([1,3,5],[2,1,2]) ax2.set_title("ax2")canvas.print_figure('demo.jpg')這兩點分別為(0, 0)和(1, 1)。(plot中的第一個表為兩個x坐標,第二個表為兩個y坐標)。這時使用的坐標系為數據坐標系(ax1.transData)。我們可以通過繪出的坐標軸讀出數據坐標的位置。
如果繪制的是標題這樣的附加信息,那么Axes坐標符合符合我們的需求。如果是整個圖像的注解,那么Figure坐標更符合需求。每一個Artist對象都有一個transform屬性,用于查詢和改變所使用的坐標系統。如果為顯示坐標,transform屬性為None。
深入基礎
from matplotlib.figure import Figure from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvasfig = Figure() canvas = FigureCanvas(fig) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])from matplotlib.path import Path import matplotlib.patches as patchesverts = [(0., 0.), (3., 0.),(4., 2.8),(5.,0.),(8.,0.),(5.5, -1.7),(7.2, -4.7),(4., -2.7),(0.8, -4.7),(2.5, -1.7),(0.,0.),]codes = [Path.MOVETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.LINETO,Path.CLOSEPOLY,]path = Path(verts, codes)patch = patches.PathPatch(path, facecolor='red') ax.add_patch(patch) ax.set_xlim(-1.8,9) ax.set_ylim(-5.7,3.8)canvas.print_figure('demo.jpg')在上面的程序中。我們首先確定頂點,然后構建了一個path對象,在codes中,我們先使用MOVETO將畫筆移動到起點,然后依次用直線連接(LINETO)(我們也可以用曲線來連線,比如CURVE4,但這里沒有用到)。 在path建立了封閉的圖形后,我們在path的基礎上構建了patch對象,是一個圖形塊。最后,我們將這個patch對象添加到預先準備好的ax上,就完成了整個繪圖。
2 應用
2.1 為項目設置matplotlib參數
如果不想每次使用matplotlib時都在代碼部分進行配置,可以修改matplotlib的文件參數。可以用matplot.get_config()命令來找到當前用戶的配置文件目錄。
配置文件包括以下配置項:
axex: 設置坐標軸邊界和表面的顏色、坐標刻度值大小和網格的顯示
backend: 設置目標暑促TkAgg和GTKAgg
figure: 控制dpi、邊界顏色、圖形大小、和子區( subplot)設置
font: 字體集(font family)、字體大小和樣式設置
grid: 設置網格顏色和線性
legend: 設置圖例和其中的文本的顯示
line: 設置線條(顏色、線型、寬度等)和標記
patch: 是填充2D空間的圖形對象,如多邊形和圓。控制線寬、顏色和抗鋸齒設置等。
savefig: 可以對保存的圖形進行單獨設置。例如,設置渲染的文件的背景為白色。
verbose: 設置matplotlib在執行期間信息輸出,如silent、helpful、debug和debug-annoying。
xticks和yticks: 為x,y軸的主刻度和次刻度設置顏色、大小、方向,以及標簽大小。
2.2 確定坐標范圍
plt.axis([xmin, xmax, ymin, ymax]): axis()命令給定了坐標范圍。
xlim(xmin, xmax)和ylim(ymin, ymax)來調整x,y坐標范圍
上圖可以看出第二張是第一張的細節圖
2.3 疊加圖
import numpy as np import matplotlib.pyplot as plt t = np.arange(0., 5., 0.2) plt.plot(t, t, 'r--', t, t**2, 'bs', t, t**3, 'g^') plt.show()2.4 plt.figure()
你可以多次使用figure命令來產生多個圖,其中,圖片號按順序增加。這里,要注意一個概念當前圖和當前坐標。所有繪圖操作僅對當前圖和當前坐標有效。
import numpy as np import matplotlib.pyplot as plt import matplotlib.patchesplt.figure(1) # 第一張圖 plt.subplot(211) # 第一張圖中的第一張子圖 plt.plot([1,2,3]) plt.subplot(212) # 第一張圖中的第二張子圖 plt.plot([4,5,6]) plt.figure(2) # 第二張圖 plt.plot([4,5,6]) # 默認創建子圖subplot(111)plt.figure(1) # 切換到figure 1 ; 子圖subplot(212)仍舊是當前圖 plt.subplot(211) # 令子圖subplot(211)成為figure1的當前圖 plt.title('Easy as 1,2,3') # 添加subplot 211 的標題
2.5 plt.text()添加文字說明
text()可以在圖中的任意位置添加文字,并支持LaTex語法
xlable(), ylable()用于添加x軸和y軸標簽
title()用于添加圖的題目
2.6 plt.annotate()文本注釋
在數據可視化的過程中,圖片中的文字經常被用來注釋圖中的一些特征。使用annotate()方法可以很方便地添加此類注釋。在使用annotate時,要考慮兩個點的坐標:被注釋的地方xy(x, y)和插入文本的地方xytext(x, y)
import numpy as np import matplotlib.pyplot as plt #import matplotlib.patchesax = plt.subplot(111) t = np.arange(0.0, 5.0, 0.01) s = np.cos(2*np.pi*t) # s=cos(2*pi*t) line, = plt.plot(t, s, lw=2) # linewidth=2 # local max是文本內容,xy是要注釋的點的坐標,xytext是文本的坐標,shrink是其收縮的長度 plt.annotate('local max', xy=(2, 1), xytext=(3, 1.5), \arrowprops=dict(facecolor='black', shrink=0.05)) plt.ylim(-2,2) plt.show()2.7 plt.xticks()和plt.yticks()設置軸記號
人為設置坐標軸的刻度顯示的值
import numpy as np import matplotlib.pyplot as plt #import matplotlib.patchesfrom pylab import * # 創建一個8 * 6 點(point)的圖,并設置分辨率為80 figure(figsize=(8,6), dpi=80) subplot(1,1,1) X = np.linspace(-np.pi, np.pi, 256,endpoint=True) C,S = np.cos(X), np.sin(X) # 繪制余弦曲線,使用藍色的、連續的、寬度為1(像素)的線條 plot(X, C, color="blue", linewidth=1.0, linestyle="-") # 繪制正弦曲線,使用綠色的、連續的、寬度為4(像素)的線條 plot(X, S, color="r", lw=4.0, linestyle="-") plt.axis([-4,4,-1.2,1.2]) # 設置軸記號 xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$']) yticks([-1, 0, +1],[r'$-1$', r'$0$', r'$+1$']) show()2.8 移動spines
Spines 是連接軸刻度標記的線,而且標明了數據區域的邊界。 他們可以被放置在任意位置。直到現在,他們仍是軸的邊界。我們將要改變現狀,因為我們想要spines 置于中間。因為有四個spine(上下左右),我們將要通過設置顏色(無)丟棄上面和右側的部分。 進而我們移動下面和左邊的線到坐標0(數據空間)。
import numpy as np import matplotlib.pyplot as plt #import matplotlib.patchesfrom pylab import * # 創建一個8 * 6 點(point)的圖,并設置分辨率為80 figure(figsize=(8,6), dpi=80) subplot(1,1,1) X = np.linspace(-np.pi, np.pi, 256,endpoint=True) C,S = np.cos(X), np.sin(X) # 繪制余弦曲線,使用藍色的、連續的、寬度為1(像素)的線條 plot(X, C, color="blue", linewidth=1.0, linestyle="-") # 繪制正弦曲線,使用綠色的、連續的、寬度為4(像素)的線條 plot(X, S, color="r", lw=4.0, linestyle="-") plt.axis([-4,4,-1.2,1.2]) # 設置軸記號 xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\[r'$-\pi$', r'$-\pi/2$', r'$0$', r'$+\pi/2$', r'$+\pi$']) yticks([-1, 0, +1],[r'$-1$', r'$0$', r'$+1$']) ax = gca() ax.spines['right'].set_color('none') # 使右邊的軸線消隱 ax.spines['top'].set_color('none') # 使上邊的軸線消隱ax.xaxis.set_ticks_position('bottom') # 設置x軸的tick的顯示位置 ax.spines['bottom'].set_position(('data',0)) ax.yaxis.set_ticks_position('left') # 設置y軸的tick的顯示位置 ax.spines['left'].set_position(('data',0)) # 消隱左邊的spine ,數據移動到坐標0plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="cosine") plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine") legend(loc='upper left') t = 2*np.pi/3 # 兩點分別是(t,0)和(t,np.cos(t)) plot([t,t],[0,np.cos(t)], color ='blue', linewidth=2.5, linestyle="--") # scatter的第一個參數是x,第二個是y,在此得到的一個點(t,np.cos(t)) scatter([t,],[np.cos(t),], 50, color ='blue') # xy()是注釋點的坐標,xytext()是文本的坐標 annotate(r'$\sin(\frac{2\pi}{3})=\frac{\sqrt{3}}{2}$',\xy=(t, np.sin(t)), xytext=(+10, +30), xycoords='data',\textcoords='offset points',fontsize=16,arrowprops=dict(arrowstyle="->", \connectionstyle="arc3,rad=.2")) plot([t,t],[0,np.sin(t)], color ='red', linewidth=2.5, linestyle="--") scatter([t,],[np.sin(t),], 50, color ='red') # annotate(r'$\cos(\frac{2\pi}{3})=-\frac{1}{2}$', xy=(t, np.cos(t)), xycoords='data', xytext=(-90, -50), textcoords='offset points', fontsize=16, arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2")) show()2.9 matplotlib.pyplot
使用plt.style.use(‘ggplot’)命令,可以作出ggplot風格的圖片。
import numpy as np import matplotlib.pyplot as plt #import matplotlib.patches import pandas as pd plt.style.use('ggplot') from sklearn import datasets,linear_model # Load data boston = datasets.load_boston() yb = boston.target.reshape(-1, 1) Xb = boston['data'][:,5].reshape(-1, 1) # Plot data plt.scatter(Xb,yb) plt.ylabel('value of house /1000 ($)') plt.xlabel('number of rooms') # Create linear regression object regr = linear_model.LinearRegression() # Train the model using the training sets regr.fit( Xb, yb) # Plot outputs plt.scatter(Xb, yb, color='black') plt.plot(Xb, regr.predict(Xb), color='blue',linewidth=3) plt.show()2.10 plt.axes()
import numpy as np import matplotlib.pyplot as plt #import matplotlib.patches import pandas as pd plt.style.use('ggplot') from sklearn import datasets,linear_model # create some data to use for the plot dt = 0.001 t = np.arange(0.0, 10.0, dt) # 構建0到10的列表,間隔0.001 r = np.exp(-t[:1000]/0.05) # 脈沖響應 x = np.random.randn(len(t)) # 產生隨機數 s = np.convolve(x, r)[:len(x)]*dt # 卷積x,r 有色噪聲 # the main axes is subplot(111) by default plt.plot(t, s) plt.axis([0, 1, 1.1*np.amin(s), 2*np.amax(s)]) plt.xlabel('time (s)') plt.ylabel('current (nA)') plt.title('Gaussian colored noise') # 這是主軸上的一個插入軸 a = plt.axes([.65, .6, .2, .2], axisbg='y') n, bins, patches = plt.hist(s, 400, normed=1) plt.title('Probability') plt.xticks([]) plt.yticks([]) #這是主軸上的另一個插入軸 a = plt.axes([0.2, 0.6, .2, .2], axisbg='y') plt.plot(t[:len(r)], r) plt.title('Impulse response') plt.xlim(0, 0.2) plt.xticks([]) plt.yticks([]) plt.show()其他的還有待學習。。。。
參考:
https://segmentfault.com/a/1190000005104723
http://www.cnblogs.com/vamei/archive/2013/01/30/2879700.html#commentform
總結
以上是生活随笔為你收集整理的Python的matplotlib(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牺牲的意思是死亡吗(牺牲的意思)
- 下一篇: python 中 feedparser的