matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地行制圖。而且也可以方便地將它作為繪圖控件,嵌入GUI應用程序中。 它的文檔相當完備,并且Gallery頁面中有上百幅縮略圖,打開之后都有源程序。因此如果你需要繪制某種類型的圖,只需要在這個頁面中瀏覽/復制/粘貼一下,基本上都能搞定。 在Linux下比較著名的數(shù)據(jù)圖工具還有gnuplot,這個是免費的,Python有一個包可以調用gnuplot,但是語法比較不習慣,而且畫圖質量不高。 而 Matplotlib則比較強:Matlab的語法、python語言、latex的畫圖質量(還可以使用內嵌的latex引擎繪制的數(shù)學公式)。 本文目錄 2. 面向對象畫圖 4. 在圖表中顯示中文 6. 對數(shù)坐標軸 7. 學習資源
matplotlib實際上是一套面向對象的繪圖庫,它所繪制的圖表中的每個繪圖元素,例如線條Line2D、文字Text、刻度等在內存中都有一個對象與之對應。 為了方便快速繪圖matplotlib通過pyplot模塊提供了一套和MATLAB類似的繪圖API,將眾多繪圖對象所構成的復雜結構隱藏在這套API內部。我們只需要調用pyplot模塊所提供的函數(shù)就可以實現(xiàn)快速繪圖以及設置圖表的各種細節(jié)。pyplot模塊雖然用法簡單,但不適合在較大的應用程序中使用。 為了將面向對象的繪圖庫包裝成只使用函數(shù)的調用接口,pyplot模塊的內部保存了當前圖表以及當前子圖等信息。當前的圖表和子圖可以使用plt.gcf()和plt.gca()獲得,分別表示"Get Current Figure"和"Get Current Axes"。在pyplot模塊中,許多函數(shù)都是對當前的Figure或Axes對象進行處理,比如說:
可以在Ipython中輸入類似"plt.plot??"的命令查看pyplot模塊的函數(shù)是如何對各種繪圖對象進行包裝的。 matplotlib所繪制的圖表的每個組成部分都和一個對象對應,我們可以通過調用這些對象的屬性設置方法set_*()或者pyplot模塊的屬性設置函數(shù)setp()設置它們的屬性值。 因為matplotlib實際上是一套面向對象的繪圖庫,因此也可以直接獲取對象的屬性 繪制一幅圖需要對許多對象的屬性進行配置,例如顏色、字體、線型等等。我們在繪圖時,并沒有逐一對這些屬性進行配置,許多都直接采用了matplotlib的缺省配置。 matplotlib將這些缺省配置保存在一個名為“matplotlibrc”的配置文件中,通過修改配置文件,我們可以修改圖表的缺省樣式。配置文件的讀入可以使用rc_params(),它返回一個配置字典;在matplotlib模塊載入時會調用rc_params(),并把得到的配置字典保存到rcParams變量中;matplotlib將使用rcParams字典中的配置進行繪圖;用戶可以直接修改此字典中的配置,所做的改變會反映到此后創(chuàng)建的繪圖元素。 繪制多子圖(快速繪圖) Matplotlib 里的常用類的包含關系為 可以使用subplot()快速繪制包含多個子圖的圖表,它的調用形式如下: subplot(numRows, numCols, plotNum) subplot將整個繪圖區(qū)域等分為numRows行* numCols列個子區(qū)域,然后按照從左到右,從上到下的順序對每個子區(qū)域進行編號,左上的子區(qū)域的編號為1。如果numRows,numCols和plotNum這三個數(shù)都小于10的話,可以把它們縮寫為一個整數(shù),例如subplot(323)和subplot(3,2,3)是相同的。subplot在plotNum指定的區(qū)域中創(chuàng)建一個軸對象。如果新創(chuàng)建的軸和之前創(chuàng)建的軸重疊的話,之前的軸將被刪除。 subplot()返回它所創(chuàng)建的Axes對象,我們可以將它用變量保存起來,然后用sca()交替讓它們成為當前Axes對象,并調用plot()在其中繪圖。 繪制多圖表(快速繪圖) 如果需要同時繪制多幅圖表,可以給figure()傳遞一個整數(shù)參數(shù)指定Figure對象的序號,如果序號所指定的Figure對象已經(jīng)存在,將不創(chuàng)建新的對象,而只是讓它成為當前的Figure對象。 import numpy as np
import matplotlib.pyplot as plt
plt.figure(1) # 創(chuàng)建圖表1 plt.figure(2) # 創(chuàng)建圖表2 ax1 = plt.subplot(211) # 在圖表2中創(chuàng)建子圖1 ax2 = plt.subplot(212) # 在圖表2中創(chuàng)建子圖2 x = np.linspace(0, 3, 100) for i in xrange(5): plt.figure(1) #? # 選擇圖表1 plt.plot(x, np.exp(i*x/3)) plt.sca(ax1) #? # 選擇圖表2的子圖1 plt.plot(x, np.sin(i*x)) plt.sca(ax2) # 選擇圖表2的子圖2 plt.plot(x, np.cos(i*x)) plt.show() matplotlib的缺省配置文件中所使用的字體無法正確顯示中文。為了讓圖表能正確顯示中文,可以有幾種解決方案。
比較簡便的方式是,中文字符串用unicode格式,例如:u''測試中文顯示'',代碼文件編碼使用utf-8 加上" # coding = utf-8 "一行。 matplotlib API包含有三層,Artist層處理所有的高層結構,例如處理圖表、文字和曲線等的繪制和布局。通常我們只和Artist打交道,而不需要關心底層的繪制細節(jié)。 直接使用Artists創(chuàng)建圖表的標準流程如下:
import matplotlib.pyplot as plt X1 = range(0, 50) Y1 = [num**2 for num in X1] # y = x^2 X2 = [0, 1] Y2 = [0, 1] # y = x Fig = plt.figure(figsize=(8,4)) # Create a `figure' instance Ax = Fig.add_subplot(111) # Create a `axes' instance in the figure Ax.plot(X1, Y1, X2, Y2) # Create a Line2D instance in the axes Fig.show() Fig.savefig("test.pdf")
參考: 《Python科學計算》(Numpy視頻) matplotlib-繪制精美的圖表(快速繪圖)(面向對象繪圖)(深入淺出適合系統(tǒng)學習) 什么是 Matplotlib (主要講面向對象繪圖,對于新手可能有點亂)
matplotlib還提供了一個名為pylab的模塊,其中包括了許多NumPy和pyplot模塊中常用的函數(shù),方便用戶快速進行計算和繪圖,十分適合在IPython交互式環(huán)境中使用。這里使用下面的方式載入pylab模塊: >>> import pylab as pl 1 安裝numpy和matplotlib >>> import numpy >>> import matplotlib
2 兩種常用圖類型:Line and scatter plots(使用plot()命令), histogram(使用hist()命令) 2.1 折線圖&散點圖 Line and scatter plots 2.1.1 折線圖 Line plots(關聯(lián)一組x和y值的直線) import numpy as np
import pylab as pl
x = [1, 2, 3, 4, 5]# Make an array of x values y = [1, 4, 9, 16, 25]# Make an array of y values for each x value pl.plot(x, y)# use pylab to plot x and y pl.show()# show the plot on the screen
2.1.2 散點圖 Scatter plots 把pl.plot(x, y)改成pl.plot(x, y, 'o')即可,下圖的藍色版本
2.2 美化 Making things look pretty 2.2.1 線條顏色 Changing the line color 紅色:把pl.plot(x, y, 'o')改成pl.plot(x, y, ’or’)
2.2.2 線條樣式 Changing the line style 虛線:plot(x,y, '--')
2.2.3 marker樣式 Changing the marker style 藍色星型markers:plot(x,y, ’b*’)
2.2.4 圖和軸標題以及軸坐標限度 Plot and axis titles and limits import numpy as np
import pylab as pl
x = [1, 2, 3, 4, 5]# Make an array of x values y = [1, 4, 9, 16, 25]# Make an array of y values for each x value pl.plot(x, y)# use pylab to plot x and y pl.title(’Plot of y vs. x’)# give plot a title pl.xlabel(’x axis’)# make axis labels pl.ylabel(’y axis’) pl.xlim(0.0, 7.0)# set axis limits pl.ylim(0.0, 30.) pl.show()# show the plot on the screen
2.2.5 在一個坐標系上繪制多個圖 Plotting more than one plot on the same set of axes 做法是很直接的,依次作圖即可: import numpy as np
import pylab as pl
x1 = [1, 2, 3, 4, 5]# Make x, y arrays for each graph y1 = [1, 4, 9, 16, 25] x2 = [1, 2, 4, 6, 8] y2 = [2, 4, 8, 12, 16] pl.plot(x1, y1, ’r’)# use pylab to plot x and y pl.plot(x2, y2, ’g’) pl.title(’Plot of y vs. x’)# give plot a title pl.xlabel(’x axis’)# make axis labels pl.ylabel(’y axis’) pl.xlim(0.0, 9.0)# set axis limits pl.ylim(0.0, 30.) pl.show()# show the plot on the screen
2.2.6 圖例 Figure legends pl.legend((plot1, plot2), (’label1, label2’), 'best’, numpoints=1) 其中第三個參數(shù)表示圖例放置的位置:'best’‘upper right’, ‘upper left’, ‘center’, ‘lower left’, ‘lower right’. 如果在當前figure里plot的時候已經(jīng)指定了label,如plt.plot(x,z,label=" import numpy as np
import pylab as pl
x1 = [1, 2, 3, 4, 5]# Make x, y arrays for each graph y1 = [1, 4, 9, 16, 25] x2 = [1, 2, 4, 6, 8] y2 = [2, 4, 8, 12, 16] plot1 = pl.plot(x1, y1, ’r’)# use pylab to plot x and y : Give your plots names plot2 = pl.plot(x2, y2, ’go’) pl.title(’Plot of y vs. x’)# give plot a title pl.xlabel(’x axis’)# make axis labels pl.ylabel(’y axis’) pl.xlim(0.0, 9.0)# set axis limits pl.ylim(0.0, 30.) pl.legend([plot1, plot2], (’red line’, ’green circles’), ’best’, numpoints=1)# make legend pl.show()# show the plot on the screen
2.3 直方圖 Histograms import numpy as np
import pylab as pl
# make an array of random numbers with a gaussian distribution with # mean = 5.0 # rms = 3.0 # number of points = 1000 data = np.random.normal(5.0, 3.0, 1000)
# make a histogram of the data array
pl.hist(data)
# make plot labels pl.xlabel(’data’)
pl.show() 如果不想要黑色輪廓可以改為pl.hist(data, histtype=’stepfilled’)
2.3.1 自定義直方圖bin寬度 Setting the width of the histogram bins manually 增加這兩行 bins = np.arange(-5., 16., 1.) #浮點數(shù)版本的range
3 同一畫板上繪制多幅子圖 Plotting more than one axis per canvas 如果需要同時繪制多幅圖表的話,可以是給figure傳遞一個整數(shù)參數(shù)指定圖標的序號,如果所指定 fig1 = pl.figure(1) You can play around with plotting a variety of layouts. For example, Fig. 11 is created using the following commands: f1 = pl.figure(1) 當繪圖對象中有多個軸的時候,可以通過工具欄中的Configure Subplots按鈕,交互式地調節(jié)軸之間的間距和軸與邊框之間的距離。如果希望在程序中調節(jié)的話,可以調用subplots_adjust函數(shù),它有l(wèi)eft, right, bottom, top, wspace, hspace等幾個關鍵字參數(shù),這些參數(shù)的值都是0到1之間的小數(shù),它們是以繪圖區(qū)域的寬高為1進行正規(guī)化之后的坐標或者長度。 pl.subplots_adjust(left=0.08, right=0.95, wspace=0.25, hspace=0.45)
4 繪制文件中的數(shù)據(jù)Plotting data contained in files 4.1 從Ascii文件中讀取數(shù)據(jù) Reading data from ascii files 讀取文件的方法很多,這里只介紹一種簡單的方法,更多的可以參考官方文檔和NumPy快速處理數(shù)據(jù)(文件存取)。 numpy的loadtxt方法可以直接讀取如下文本數(shù)據(jù)到numpy二維數(shù)組 ********************************************** # fakedata.txt ********************************************** import numpy as np
import pylab as pl
# Use numpy to load the data contained in the file # ’fakedata.txt’ into a 2-D array called data
data = np.loadtxt(’fakedata.txt’)
# plot the first column as x, and second column as y pl.plot(data[:,0], data[:,1], ’ro’) pl.xlabel(’x’) pl.ylabel(’y’) pl.xlim(0.0, 10.) pl.show()
4.2 寫入數(shù)據(jù)到文件 Writing data to a text file 寫文件的方法也很多,這里只介紹一種可用的寫入文本文件的方法,更多的可以參考官方文檔。 import numpy as np
# Let’s make 2 arrays (x, y) which we will write to a file
# x is an array containing numbers 0 to 10, with intervals of 1 x = np.arange(0.0, 10., 1.) # y is an array containing the values in x, squared y = x*x print ’x = ’, x
print ’y = ’, y
# Now open a file to write the data to # ’w’ means open for ’writing’
file = open(’testdata.txt’, ’w’)
# loop over each line you want to write to file
for i in range(len(x)): # make a string for each line you want to write # ’\t’ means ’tab’ # ’\n’ means ’newline’ # ’str()’ means you are converting the quantity in brackets to a string type
txt = str(x[i]) + ’\t’ + str(y[i]) + ’ \n’ # write the txt to the file
file.write(txt)
# Close your file file.close()
這部分是翻譯自:Python Plotting Beginners Guide Matlplotlib對LaTeX有一定的支持,如果記得使用raw字符串語法會很自然:
在matplotlib里面,可以使用LaTex的命令來編輯公式,只需要在字符串前面加一個“r”即可 Here is a simple example:
produces “alpha > beta”. Whereas this:
produces "". 這里給大家看一個簡單的例子。
程序執(zhí)行結果如圖3所示,這實際上是一個power-law的例子,有興趣的朋友可以繼續(xù)google之。 再看一個《用Python做科學計算》中的簡單例子,下面的兩行程序通過調用plot函數(shù)在當前的繪圖對象中進行繪圖:
plot函數(shù)的調用方式很靈活,第一句將x,y數(shù)組傳遞給plot之后,用關鍵字參數(shù)指定各種屬性:
詳細的可以參考matplotlib官方教程: Writing mathematical expressions
有幾個問題:
參考文獻自動搜集管理完美攻略(圖文版):Latex+Lyx+Zotero
在實際中,我們可能經(jīng)常會用到對數(shù)坐標軸,這時可以用下面的三個函數(shù)來實現(xiàn) ax.semilogx(x,y) #x軸為對數(shù)坐標軸 ax.semilogy(x,y) #y軸為對數(shù)坐標軸 ax.loglog(x,y) #雙對數(shù)坐標軸 Gnuplot的介紹 官方英文資料:
IBM:基于 Python Matplotlib 模塊的高質量圖形輸出(2005年的文章有點舊) matplotlib技巧集(繪制不連續(xù)函數(shù)的不連續(xù)點;參數(shù)曲線上繪制方向箭頭;修改缺省刻度數(shù)目;Y軸不同區(qū)間使用不同顏色填充的曲線區(qū)域。) |
|