matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地進行製圖。而且也可以方便地將它作爲繪圖控件,嵌入GUI應用程序中。
它的文檔相當完備,並且 Gallery頁面 中有上百幅縮略圖,打開之後都有源程序。因此如果你需要繪製某種類型的圖,只需要在這個頁面中瀏覽/複製/粘貼一下,基本上都能搞定。
在Linux下比較著名的數據圖工具還有gnuplot,這個是免費的,Python有一個包可以調用gnuplot,但是語法比較不習慣,而且畫圖質量不高。
而 Matplotlib則比較強:Matlab的語法、python語言、latex的畫圖質量(還可以使用內嵌的latex引擎繪製的數學公式)。
快速繪圖
matplotlib的pyplot子庫提供了和matlab類似的繪圖API,方便用戶快速繪製2D圖表。例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#
coding=gbk '' ' Created
on Jul 12 ,
2014 python
科學計算學習:numpy快速處理數據測試 @author :
皮皮 '' ' import
string import
matplotlib.pyplot as plt import
numpy as np if
__name__ == '__main__' :
file
= open(E:machine_learningdatasetshousing_datahousing_data_ages.txt, 'r' ) linesList
= file.readlines() #
print(linesList) linesList
= [line.strip().split(,) for
line in linesList] file.close()
print(linesList:) print(linesList) #
years = [string.atof(x[ 0 ])
for
x in linesList] years
= [x[ 0 ]
for
x in linesList] print(years) price
= [x[ 1 ]
for
x in linesList] print(price) plt.plot(years,
price, 'b*' )#,label=$cos(x^ 2 )$) plt.plot(years,
price, 'r' ) plt.xlabel(years(+ 2000 )) plt.ylabel(housing
average price(* 2000
yuan)) plt.ylim( 0 ,
15 ) plt.title( 'line_regression
& gradient decrease' ) plt.legend() plt.show() |
matplotlib中的快速繪圖的函數庫可以通過如下語句載入:
1
|
import
matplotlib.pyplot as plt |
pylab模塊
matplotlib還提供了名爲pylab的模塊,其中包括了許多numpy和pyplot中常用的函數,方便用戶快速進行計算和繪圖,可以用於IPython中的快速交互式使用。
接下來調用figure創建一個繪圖對象,並且使它成爲當前的繪圖對象。
1
|
plt.figure(figsize=( 8 , 4 )) |
也可以不創建繪圖對象直接調用接下來的plot函數直接繪圖,matplotlib會爲我們自動創建一個繪圖對象。如果需要同時繪製多幅圖表的話,可以是給figure傳遞一個整數參數指定圖標的序號,如果所指定序號的繪圖對象已經存在的話,將不創建新的對象,而只是讓它成爲當前繪圖對象。
通過figsize參數可以指定繪圖對象的寬度和高度,單位爲英寸;dpi參數指定繪圖對象的分辨率,即每英寸多少個像素,缺省值爲80。因此本例中所創建的圖表窗口的寬度爲8*80 = 640像素。
但是用工具欄中的保存按鈕保存下來的png圖像的大小是800*400像素。這是因爲保存圖表用的函數savefig使用不同的DPI配置,savefig函數也有一個dpi參數,如果不設置的話,將使用matplotlib配置文件中的配置,此配置可以通過如下語句進行查看:
1
2
3
|
>>>
import
matplotlib >>>
matplotlib.rcParams[savefig.dpi] 100 |
下面的兩行程序通過調用plot函數在當前的繪圖對象中進行繪圖:
1
2
|
plt.plot(years,
price, 'b*' )#,label=$cos(x^ 2 )$) plt.plot(years,
price, 'r' ) |
plot函數的調用方式很靈活,第一句將x,y數組傳遞給plot之後,用關鍵字參數指定各種屬性:
- label : 給所繪製的曲線一個名字,此名字在圖示(legend)中顯示。只要在字符串前後添加$符號,matplotlib就會使用其內嵌的latex引擎繪製的數學公式。
- color : 指定曲線的顏色
- linewidth : 指定曲線的寬度
第二句直接通過第三個參數b--指定曲線的顏色和線型,這個參數稱爲格式化參數,它能夠通過一些易記的符號快速指定曲線的樣式。其中b表示藍色,--表示線型爲虛線。
在IPython中輸入 plt.plot? 可以查看格式化字符串的詳細配置。
接下來通過一系列函數設置繪圖對象的各個屬性:
12345plt.xlabel(years(+
2000
))
plt.ylabel(housing average price(*
2000
yuan))
plt.ylim(
0
,
15
)
plt.title(
'line_regression & gradient decrease'
)
plt.legend()
- xlabel : 設置X軸的文字
- ylabel : 設置Y軸的文字
- title : 設置圖表的標題
- ylim : 設置Y軸的範圍
- legend : 顯示圖示
最後調用plt.show()顯示出我們創建的所有繪圖對象。
配置屬性
matplotlib所繪製的圖的每個組成部分都對應有一個對象,我們可以通過調用這些對象的屬性設置方法set_*或者pyplot的屬性設置函數setp設置其屬性值。例如plot函數返回一個 matplotlib.lines.Line2D 對象的列表,下面的例子顯示如何設置Line2D對象的屬性:
123456>>>
import
numpy as np
>>>
import
matplotlib.pyplot as plt
>>> x = np.arange(
0
,
5
,
0.1
)
>>> line, = plt.plot(x, x*x) # plot返回一個列表,通過line,獲取其第一個元素
>>> # 調用Line2D對象的set_*方法設置屬性值
>>> line.set_antialiased(False)
1234>>> # 同時繪製sin和cos兩條曲線,lines是一個有兩個Line2D對象的列表
>>> lines = plt.plot(x, np.sin(x), x, np.cos(x)) #
>>> # 調用setp函數同時配置多個Line2D對象的多個屬性值
>>> plt.setp(lines, color=r, linewidth=
2.0
)
這段例子中,通過調用Line2D對象line的set_antialiased方法,關閉對象的反鋸齒效果。或者通過調用plt.setp函數配置多個Line2D對象的顏色和線寬屬性。
同樣我們可以通過調用Line2D對象的get_*方法,或者plt.getp函數獲取對象的屬性值:
12345678910>>> line.get_linewidth()
1.0
>>> plt.getp(lines[
0
], color) # 返回color屬性
'r'
>>> plt.getp(lines[
1
]) # 輸出全部屬性
alpha =
1.0
animated = False
antialiased or aa = True
axes = Axes(
0.125
,
0.1
;
0
.775x0.
8
)
... ...
注意getp函數只能對一個對象進行操作,它有兩種用法:
- 指定屬性名:返回對象的指定屬性的值
- 不指定屬性名:打印出對象的所有屬性和其值
matplotlib的整個圖表爲一個Figure對象,此對象在調用plt.figure函數時返回,我們也可以通過plt.gcf函數獲取當前的繪圖對象:
12345>>> f = plt.gcf()
>>> plt.getp(f)
alpha =
1.0
animated = False
...
Figure對象有一個axes屬性,其值爲AxesSubplot對象的列表,每個AxesSubplot對象代表圖表中的一個子圖,前面所繪製的圖表只包含一個子圖,當前子圖也可以通過plt.gca獲得:
12345>>> plt.getp(f, axes)
[<matplotlib.axes.axessubplot
0x05cdd170
=
""
at=
""
object=
""
>]
>>> plt.gca()
<matplotlib.axes.axessubplot
0x05cdd170
=
""
at=
""
object=
""
>
</matplotlib.axes.axessubplot></matplotlib.axes.axessubplot>
用plt.getp可以發現AxesSubplot對象有很多屬性,例如它的lines屬性爲此子圖所包括的 Line2D 對象列表:
123456>>> alllines = plt.getp(plt.gca(), lines)
>>> alllines
>>> alllines[
0
] == line # 其中的第一條曲線就是最開始繪製的那條曲線
True
通過這種方法我們可以很容易地查看對象的屬性和它們之間的包含關係,找到需要配置的屬性。
Python圖表繪製:matplotlib繪圖庫入門
matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的命令API,十分適合交互式地行製圖。而且也可以方便地將它作爲繪圖控件,嵌入GUI應用程序中。
它的文檔相當完備,並且Gallery頁面中有上百幅縮略圖,打開之後都有源程序。因此如果你需要繪製某種類型的圖,只需要在這個頁面中瀏覽/複製/粘貼一下,基本上都能搞定。
在Linux下比較著名的數據圖工具還有gnuplot,這個是免費的,Python有一個包可以調用gnuplot,但是語法比較不習慣,而且畫圖質量不高。
而 Matplotlib則比較強:Matlab的語法、python語言、latex的畫圖質量(還可以使用內嵌的latex引擎繪製的數學公式)。
matplotlib實際上是一套面向對象的繪圖庫,它所繪製的圖表中的每個繪圖元素,例如線條Line2D、文字Text、刻度等在內存中都有一個對象與之對應。
plt.plot()實際上會通過plt.gca()獲得當前的Axes對象ax,然後再調用ax.plot()方法實現真正的繪圖。
可以在Ipython中輸入類似plt.plot??的命令查看pyplot模塊的函數是如何對各種繪圖對象進行包裝的。
matplotlib所繪製的圖表的每個組成部分都和一個對象對應,我們可以通過調用這些對象的屬性設置方法set_*()或者pyplot模塊的屬性設置函數setp()設置它們的屬性值。
因爲matplotlib實際上是一套面向對象的繪圖庫,因此也可以直接獲取對象的屬性
繪製一幅圖需要對許多對象的屬性進行配置,例如顏色、字體、線型等等。我們在繪圖時,並沒有逐一對這些屬性進行配置,許多都直接採用了matplotlib的缺省配置。
可以使用subplot()快速繪製包含多個子圖的圖表,它的調用形式如下:
12subplot(numRows, numCols, plotNum)
subplot()返回它所創建的Axes對象,我們可以將它用變量保存起來,然後用sca()交替讓它們成爲當前Axes對象,並調用plot()在其中繪圖。
如果需要同時繪製多幅圖表,可以給figure()傳遞一個整數參數指定Figure對象的序號,如果序號所指定的Figure對象已經存在,將不創建新的對象,而只是讓它成爲當前的Figure對象。
12import
numpy as np
12import
matplotlib.pyplot as plt
112plt.figure(
1
) # 創建圖表
1
12plt.figure(
2
) # 創建圖表
2
12ax1 = plt.subplot(
211
) # 在圖表
2
中創建子圖
1
12ax2 = plt.subplot(
212
) # 在圖表
2
中創建子圖
2
112x = np.linspace(
0
,
3
,
100
)
12for
i in xrange(
5
):
12plt.figure(
1
) #? # 選擇圖表
1
12plt.plot(x, np.exp(i*x/
3
))
12plt.sca(ax1) #? # 選擇圖表
2
的子圖
1
12plt.plot(x, np.sin(i*x))
12plt.sca(ax2) # 選擇圖表
2
的子圖
2
12plt.plot(x, np.cos(i*x))
112plt.show()
vc3RhdGljL2Jvb2tzL3NjaXB5L19pbWFnZXMvbWF0cGxvdGxpYl9tdWx0aV9maWd1cmUucG5n" height="283" src="/uploadfile/Collfiles/20140714/20140714083842244.png" width="665" />
matplotlib的缺省配置文件中所使用的字體無法正確顯示中文。爲了讓圖表能正確顯示中文,可以有幾種解決方案。
- 在程序中直接指定字體。
- 在程序開頭修改配置字典rcParams。
- 修改配置文件。
比較簡便的方式是,中文字符串用unicode格式,例如:u''測試中文顯示'',代碼文件編碼使用utf-8 加上 # coding = utf-8 一行。
matplotlib API包含有三層,Artist層處理所有的高層結構,例如處理圖表、文字和曲線等的繪製和佈局。通常我們只和Artist打交道,而不需要關心底層的繪製細節。
- 創建Figure對象
- 用Figure對象創建一個或者多個Axes或者Subplot對象
- 調用Axies等對象的方法創建各種簡單類型的Artists
import matplotlib.pyplot as plt
1X1 = range(0, 50) Y1 = [num**2 for num in X1] # y = x^2 X2 = [0, 1] Y2 = [0, 1] # y = x
11Fig.show() Fig.savefig(test.pdf)
《Python科學計算》(Numpy視頻) matplotlib-繪製精美的圖表(快速繪圖)(面向對象繪圖)(深入淺出適合系統學習)
什麼是 Matplotlib (主要講面向對象繪圖,對於新手可能有點亂)
12>>>
import
pylab as pl
>>> import numpy
>>> numpy.__version__>>> import matplotlib
>>> matplotlib.__version__2 兩種常用圖類型:Line and scatter plots(使用plot()命令), histogram(使用hist()命令)
2.1 折線圖&散點圖 Line and scatter plots
2.1.1 折線圖 Line plots(關聯一組x和y值的直線)
12import
numpy as np
12import
pylab as pl
112x = [
1
,
2
,
3
,
4
,
5
]# Make an array of x values
12y = [
1
,
4
,
9
,
16
,
25
]# Make an array of y values
for
each x value
112pl.plot(x, y)# use pylab to plot x and y
1pl.show()# show the plot on the screen
把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
2.2.3 marker樣式 Changing the marker style
2.2.4 圖和軸標題以及軸座標限度 Plot and axis titles and limits
12import
numpy as np
12import
pylab as pl
112x = [
1
,
2
,
3
,
4
,
5
]# Make an array of x values
12y = [
1
,
4
,
9
,
16
,
25
]# Make an array of y values
for
each x value
12pl.plot(x, y)# use pylab to plot x and y
112pl.title(’Plot of y vs. x’)# give plot a title
12pl.xlabel(’x axis’)# make axis labels
12pl.ylabel(’y axis’)
112pl.xlim(
0.0
,
7.0
)# set axis limits
12pl.ylim(
0.0
,
30
.)
11pl.show()# show the plot on the screen
2.2.5 在一個座標系上繪製多個圖 Plotting more than one plot on the same set of axes
12import
numpy as np
12import
pylab as pl
112x1 = [
1
,
2
,
3
,
4
,
5
]# Make x, y arrays
for
each graph
12y1 = [
1
,
4
,
9
,
16
,
25
]
12x2 = [
1
,
2
,
4
,
6
,
8
]
12y2 = [
2
,
4
,
8
,
12
,
16
]
112pl.plot(x1, y1, ’r’)# use pylab to plot x and y
12pl.plot(x2, y2, ’g’)
112pl.title(’Plot of y vs. x’)# give plot a title
12pl.xlabel(’x axis’)# make axis labels
12pl.ylabel(’y axis’)
1112pl.xlim(
0.0
,
9.0
)# set axis limits
12pl.ylim(
0.0
,
30
.)
111pl.show()# show the plot on the screen
pl.legend((plot1, plot2), (’label1, label2’), 'best’, numpoints=1)
其中第三個參數表示圖例放置的位置:'best’‘upper right’, ‘upper left’, ‘center’, ‘lower left’, ‘lower right’.
如果在當前figure裏plot的時候已經指定了label,如plt.plot(x,z,label=
cos(x2) ),直接調用plt.legend()就可以了哦。12import
numpy as np
12import
pylab as pl
112x1 = [
1
,
2
,
3
,
4
,
5
]# Make x, y arrays
for
each graph
12y1 = [
1
,
4
,
9
,
16
,
25
]
12x2 = [
1
,
2
,
4
,
6
,
8
]
12y2 = [
2
,
4
,
8
,
12
,
16
]
112plot1 = pl.plot(x1, y1, ’r’)# use pylab to plot x and y : Give your plots names
12plot2 = pl.plot(x2, y2, ’go’)
112pl.title(’Plot of y vs. x’)# give plot a title
12pl.xlabel(’x axis’)# make axis labels
12pl.ylabel(’y axis’)
1112pl.xlim(
0.0
,
9.0
)# set axis limits
12pl.ylim(
0.0
,
30
.)
1112pl.legend([plot1, plot2], (’red line’, ’green circles’), ’best’, numpoints=
1
)# make legend
1pl.show()# show the plot on the screen
12import
numpy as np
12import
pylab as pl
112# make an array of random numbers with a gaussian distribution with
12# mean =
5.0
12# rms =
3.0
12# number of points =
1000
12data = np.random.normal(
5.0
,
3.0
,
1000
)
112# make a histogram of the data array
12pl.hist(data)
112# make plot labels
12pl.xlabel(’data’)
1pl.show()
如果不想要黑色輪廓可以改爲pl.hist(data, histtype=’stepfilled’)
2.3.1 自定義直方圖bin寬度 Setting the width of the histogram bins manually
bins = np.arange(-5., 16., 1.) #浮點數版本的range
pl.hist(data, bins, histtype=’stepfilled’)3 同一畫板上繪製多幅子圖 Plotting more than one axis per canvas
如果需要同時繪製多幅圖表的話,可以是給figure傳遞一個整數參數指定圖標的序號,如果所指定
序號的繪圖對象已經存在的話,將不創建新的對象,而只是讓它成爲當前繪圖對象。f1 = pl.figure(1)
pl.subplot(221)
pl.subplot(222)
pl.subplot(212)pl.subplots_adjust(left=0.08, right=0.95, wspace=0.25, hspace=0.45)
4 繪製文件中的數據Plotting data contained in files
4.1 從Ascii文件中讀取數據 Reading data from ascii files
讀取文件的方法很多,這裏只介紹一種簡單的方法,更多的可以參考官方文檔和NumPy快速處理數據(文件存取)。
numpy的loadtxt方法可以直接讀取如下文本數據到numpy二維數組
**********************************************
**********************************************
12import
numpy as np
12import
pylab as pl
112# Use numpy to load the data contained in the file
12# ’fakedata.txt’ into a
2
-D array called data
12data = np.loadtxt(’fakedata.txt’)
112# plot the first column as x, and second column as y
12pl.plot(data[:,
0
], data[:,
1
], ’ro’)
12pl.xlabel(’x’)
12pl.ylabel(’y’)
12pl.xlim(
0.0
,
10
.)
1pl.show()
4.2 寫入數據到文件 Writing data to a text file
寫文件的方法也很多,這裏只介紹一種可用的寫入文本文件的方法,更多的可以參考官方文檔。
12import
numpy as np
12# Let’s make
2
arrays (x, y) which we will write to a file
12# x is an array containing numbers
0
to
10
, with intervals of
1
12x = np.arange(
0.0
,
10
.,
1
.)
12# y is an array containing the values in x, squared
12y = x*x
12print ’x = ’, x
12print ’y = ’, y
112# Now open a file to write the data to
12# ’w’ means open
for
’writing’
12file = open(’testdata.txt’, ’w’)
12# loop over each line you want to write to file
12for
i in range(len(x)):
12# make a string
for
each line you want to write
12# ’ ’ means ’tab’
123# ’
’ means ’newline’
12# ’str()’ means you are converting the quantity in brackets to a string type
123txt = str(x[i]) + ’ ’ + str(y[i]) + ’
’
12# write the txt to the file
12file.write(txt)
12# Close your file
12file.close()
這部分是翻譯自:Python Plotting Beginners Guide
Matlplotlib對LaTeX有一定的支持,如果記得使用raw字符串語法會很自然:
在matplotlib裏面,可以使用LaTex的命令來編輯公式,只需要在字符串前面加一個“r”即可
import matplotlib.pyplot as plt
x = arange(1,1000,1)
r = -2
c = 5
y = [5*(a**r) for a in x]程序執行結果如圖3所示,這實際上是一個power-law的例子,有興趣的朋友可以繼續google之。
再看一個《用Python做科學計算》中的簡單例子,下面的兩行程序通過調用plot函數在當前的繪圖對象中進行繪圖:
plt.plot(x,y,label=
sin(x) ,color=red,linewidth=2)
plt.plot(x,z,b--,label=cos(x2) )plot函數的調用方式很靈活,第一句將x,y數組傳遞給plot之後,用關鍵字參數指定各種屬性:
- label : 給所繪製的曲線一個名字,此名字在圖示(legend)中顯示。只要在字符串前後添加$符號,matplotlib就會使用其內嵌的latex引擎繪製的數學公式。
- color : 指定曲線的顏色
- linewidth : 指定曲線的寬度
Writing mathematical expressions
- Subscripts and superscripts
- Fractions, binomials and stacked numbers
- Radicals
- Fonts
- Custom fonts
- Accents
- Symbols
- Example
- usetex with unicode
- Postscript options
- Possible hangups
- Troubleshooting
- matplotlib.rcParams屬性字典
- 想要它正常工作,在matplotlibrc配置文件中需要設置text.markup = tex。
- 如果你希望圖表中所有的文字(包括座標軸刻度標記)都是LaTeX'd,需要在matplotlibrc中設置text.usetex = True。如果你使用LaTeX撰寫論文,那麼這一點對於使圖表和論文中其餘部分保持一致是很有用的。
參考文獻自動蒐集管理完美攻略(圖文版):Latex+Lyx+Zotero
在實際中,我們可能經常會用到對數座標軸,這時可以用下面的三個函數來實現
- Gnuplot簡介
- IBM:gnuplot 讓您的數據可視化,Linux 上的數據可視化工具
- 利用Python繪製論文圖片: Gnuplot,pylab
- matplotlib下載及API手冊地址
- Screenshots:example figures
- Gallery:Click on any image to see full size image and source code
- matplotlib所使用的數學庫numpy下載及API手冊
IBM:基於 Python Matplotlib 模塊的高質量圖形輸出(2005年的文章有點舊)
matplotlib技巧集(繪製不連續函數的不連續點;參數曲線上繪製方向箭頭;修改缺省刻度數目;Y軸不同區間使用不同顏色填充的曲線區域。)
Python:使用matp繪製不連續函數的不連續點;參數曲線上繪製方向箭頭;修改缺省刻度數目;Y軸不同區間使用不同顏色填充的曲線區域。lotlib繪製圖表