天天看點

Python圖表繪制:matplotlib繪圖庫入門

matplotlib 是python最著名的繪圖庫,它提供了一整套和matlab相似的指令API,十分适合互動式地行制圖。而且也可以友善地将它作為繪圖控件,嵌入GUI應用程式中。

它的文檔相當完備,并且Gallery頁面中有上百幅縮略圖,打開之後都有源程式。是以如果你需要繪制某種類型的圖,隻需要在這個頁面中浏覽/複制/粘貼一下,基本上都能搞定。

在Linux下比較著名的資料圖工具還有gnuplot,這個是免費的,Python有一個包可以調用gnuplot,但是文法比較不習慣,而且畫圖品質不高。

Matplotlib.pyplot快速繪圖

matplotlib實際上是一套面向對象的繪圖庫,它所繪制的圖表中的每個繪圖元素,例如線條Line2D、文字Text、刻度等在記憶體中都有一個對象與之對應。

為了友善快速繪圖matplotlib通過pyplot子產品提供了一套和MATLAB類似的繪圖API,将衆多繪圖對象所構成的複雜結構隐藏在這套API内部。我們隻需要調用pyplot子產品所提供的函數就可以實作快速繪圖以及設定圖表的各種細節。pyplot子產品雖然用法簡單,但不适合在較大的應用程式中使用。

為了将面向對象的繪圖庫包裝成隻使用函數的調用接口,pyplot子產品的内部儲存了目前圖表以及目前子圖等資訊。目前的圖表和子圖可以使用plt.gcf()和plt.gca()獲得,分别表示"Get Current Figure"和"Get Current Axes"。在pyplot子產品中,許多函數都是對目前的Figure或Axes對象進行處理,比如說:

plt.plot()實際上會通過plt.gca()獲得目前的Axes對象ax,然後再調用ax.plot()方法實作真正的繪圖。

可以在Ipython中輸入類似"plt.plot??"的指令檢視pyplot子產品的函數是如何對各種繪圖對象進行包裝的。

<a href="http://hyry.dip.jp/tech/book/page/scipy/matplotlib_fast_plot.html#id3" target="_blank">配置屬性</a>

matplotlib所繪制的圖表的每個組成部分都和一個對象對應,我們可以通過調用這些對象的屬性設定方法set_*()或者pyplot子產品的屬性設定函數setp()設定它們的屬性值。

因為matplotlib實際上是一套面向對象的繪圖庫,是以也可以直接擷取對象的屬性

<a href="http://hyry.dip.jp/tech/book/page/scipy/matplotlib_fast_plot.html#id5" target="_blank">配置檔案</a>

繪制一幅圖需要對許多對象的屬性進行配置,例如顔色、字型、線型等等。我們在繪圖時,并沒有逐一對這些屬性進行配置,許多都直接采用了matplotlib的預設配置。

matplotlib将這些預設配置儲存在一個名為“matplotlibrc”的配置檔案中,通過修改配置檔案,我們可以修改圖表的預設樣式。配置檔案的讀入可以使用rc_params(),它傳回一個配置字典;在matplotlib子產品載入時會調用rc_params(),并把得到的配置字典儲存到rcParams變量中;matplotlib将使用rcParams字典中的配置進行繪圖;使用者可以直接修改此字典中的配置,所做的改變會反映到此後建立的繪圖元素。

Matplotlib 裡的常用類的包含關系為 <code>Figure -&gt; Axes -&gt; (Line2D, Text, etc.)</code>一個Figure對象可以包含多個子圖(Axes),在matplotlib中用Axes對象表示一個繪圖區域,可以了解為子圖。

可以使用subplot()快速繪制包含多個子圖的圖表,它的調用形式如下:

subplot将整個繪圖區域等分為numRows行* numCols列個子區域,然後按照從左到右,從上到下的順序對每個子區域進行編号,左上的子區域的編号為1。如果numRows,numCols和plotNum這三個數都小于10的話,可以把它們縮寫為一個整數,例如subplot(323)和subplot(3,2,3)是相同的。subplot在plotNum指定的區域中建立一個軸對象。如果新建立的軸和之前建立的軸重疊的話,之前的軸将被删除。

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205231144091047.png" target="_blank"></a>

subplot()傳回它所建立的Axes對象,我們可以将它用變量儲存起來,然後用sca()交替讓它們成為目前Axes對象,并調用plot()在其中繪圖。

如果需要同時繪制多幅圖表,可以給figure()傳遞一個整數參數指定Figure對象的序号,如果序号所指定的Figure對象已經存在,将不建立新的對象,而隻是讓它成為目前的Figure對象。

<a href="http://hyry.dip.jp/tech/book/page/scipy/matplotlib_fast_plot.html#id6" target="_blank">在圖表中顯示中文</a>

matplotlib的預設配置檔案中所使用的字型無法正确顯示中文。為了讓圖表能正确顯示中文,可以有幾種解決方案。

在程式中直接指定字型。

在程式開頭修改配置字典rcParams。

修改配置檔案。

面向對象畫圖

matplotlib API包含有三層,Artist層處理所有的高層結構,例如處理圖表、文字和曲線等的繪制和布局。通常我們隻和Artist打交道,而不需要關心底層的繪制細節。

直接使用Artists建立圖表的标準流程如下:

建立Figure對象

用Figure對象建立一個或者多個Axes或者Subplot對象

調用Axies等對象的方法建立各種簡單類型的Artists

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")

參考:

Matplotlib.pylab快速繪圖

matplotlib還提供了一個名為pylab的子產品,其中包括了許多NumPy和pyplot子產品中常用的函數,友善使用者快速進行計算和繪圖,十分适合在IPython互動式環境中使用。這裡使用下面的方式載入pylab子產品:

1 安裝numpy和matplotlib

&gt;&gt;&gt; import numpy

&gt;&gt;&gt; numpy.__version__

&gt;&gt;&gt; import matplotlib

&gt;&gt;&gt; matplotlib.__version__

2 兩種常用圖類型:Line and scatter plots(使用plot()指令), histogram(使用hist()指令)

2.1 折線圖&amp;散點圖 Line and scatter plots

2.1.1 折線圖 Line plots(關聯一組x和y值的直線)

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001187415.png" target="_blank"></a>

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’)

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001191710.png" target="_blank"></a>

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001214610.png" target="_blank"></a>

2.2.2 線條樣式 Changing the line style

虛線:plot(x,y, '--')

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001221097.png" target="_blank"></a>

2.2.3 marker樣式 Changing the marker style

藍色星型markers:plot(x,y, ’b*’)

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001244803.png" target="_blank"></a>

2.2.4 圖和軸标題以及軸坐标限度 Plot and axis titles and limits

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001269588.png" target="_blank"></a>

2.2.5 在一個坐标系上繪制多個圖 Plotting more than one plot on the same set of axes

做法是很直接的,依次作圖即可:

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001283568.png" target="_blank"></a>

2.2.6  圖例 Figure legends

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()就可以了哦。

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001293718.png" target="_blank"></a>

2.3 直方圖 Histograms

如果不想要黑色輪廓可以改為pl.hist(data, histtype=’stepfilled’)

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001317141.png" target="_blank"></a>

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’)

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001329484.png" target="_blank"></a>

3 同一畫闆上繪制多幅子圖 Plotting more than one axis per canvas

如果需要同時繪制多幅圖表的話,可以是給figure傳遞一個整數參數指定圖示的序号,如果所指定

序号的繪圖對象已經存在的話,将不建立新的對象,而隻是讓它成為目前繪圖對象。

fig1 = pl.figure(1)

pl.subplot(211)

subplot(211)把繪圖區域等分為2行*1列共兩個區域, 然後在區域1(上區域)中建立一個軸對象. pl.subplot(212)在區域2(下區域)建立一個軸對象。

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230001347367.png" target="_blank"></a>

You can play around with plotting a variety of layouts. For example, Fig. 11 is created using the following commands:

f1 = pl.figure(1)

pl.subplot(221)

pl.subplot(222)

pl.subplot(212)

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230932333763.png" target="_blank"></a>

當繪圖對象中有多個軸的時候,可以通過工具欄中的Configure Subplots按鈕,互動式地調節軸之間的間距和軸與邊框之間的距離。如果希望在程式中調節的話,可以調用subplots_adjust函數,它有left, right, bottom, top, wspace, hspace等幾個關鍵字參數,這些參數的值都是0到1之間的小數,它們是以繪圖區域的寬高為1進行正規化之後的坐标或者長度。

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的loadtxt方法可以直接讀取如下文本資料到numpy二維數組

**********************************************

# fakedata.txt

0 0

1 1

2 4

3 9

4 16

5 25

6 36

7 49

8 64

9 81

<a href="http://images.cnblogs.com/cnblogs_com/wei-li/201205/201205230737253033.png" target="_blank"></a>

4.2 寫入資料到檔案 Writing data to a text file

寫檔案的方法也很多,這裡隻介紹一種可用的寫入文本檔案的方法,更多的可以參考官方文檔。

對LaTeX數學公式的支援

Matlplotlib對LaTeX有一定的支援,如果記得使用raw字元串文法會很自然:

xlabel(r"x2y4")

在matplotlib裡面,可以使用LaTex的指令來編輯公式,隻需要在字元串前面加一個“r”即可

Here is a simple example:

# plain text plt.title('alpha &gt; beta')

produces “alpha &gt; beta”.

Whereas this:

Python圖表繪制:matplotlib繪圖庫入門

produces "

Python圖表繪制:matplotlib繪圖庫入門

".

這裡給大家看一個簡單的例子。

import matplotlib.pyplot as plt x = arange(1,1000,1) r = -2 c = 5 y = [5*(a**r) for a in x] fig = plt.figure() ax = fig.add_subplot(111) ax.loglog(x,y,label = r"y=12σ21,c=5,σ1=2") ax.legend() ax.set_xlabel(r"x") ax.set_ylabel(r"y")

程式執行結果如圖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 : 指定曲線的寬度

詳細的可以參考matplotlib官方教程:

<a href="http://matplotlib.sourceforge.net/users/" target="_blank">Writing mathematical expressions</a>

<a href="http://matplotlib.sourceforge.net/users/#subscripts-and-superscripts" target="_blank">Subscripts and superscripts</a>

<a href="http://matplotlib.sourceforge.net/users/#fractions-binomials-and-stacked-numbers" target="_blank">Fractions, binomials and stacked numbers</a>

<a href="http://matplotlib.sourceforge.net/users/#radicals" target="_blank">Radicals</a>

<a href="http://matplotlib.sourceforge.net/users/#fonts" target="_blank">Fonts</a>

<a href="http://matplotlib.sourceforge.net/users/#custom-fonts" target="_blank">Custom fonts</a>

<a href="http://matplotlib.sourceforge.net/users/#accents" target="_blank">Accents</a>

<a href="http://matplotlib.sourceforge.net/users/#symbols" target="_blank">Symbols</a>

<a href="http://matplotlib.sourceforge.net/users/#example" target="_blank">Example</a>

<a href="http://matplotlib.sourceforge.net/users/" target="_blank">Text rendering With LaTeX</a>

<a href="http://matplotlib.sourceforge.net/users/#usetex-with-unicode" target="_blank">usetex with unicode</a>

<a href="http://matplotlib.sourceforge.net/users/#postscript-options" target="_blank">Postscript options</a>

<a href="http://matplotlib.sourceforge.net/users/#possible-hangups" target="_blank">Possible hangups</a>

<a href="http://matplotlib.sourceforge.net/users/#troubleshooting" target="_blank">Troubleshooting</a>

有幾個問題:

matplotlib.rcParams屬性字典

想要它正常工作,在matplotlibrc配置檔案中需要設定text.markup = "tex"。

如果你希望圖表中所有的文字(包括坐标軸刻度标記)都是LaTeX'd,需要在matplotlibrc中設定text.usetex = True。如果你使用LaTeX撰寫論文,那麼這一點對于使圖表和論文中其餘部分保持一緻是很有用的。

在matplotlib中使用中文字元串時記住要用unicode格式,例如:u''測試中文顯示''

<a href="http://hi.baidu.com/step_1/blog/item/72231a2c53348af28b13999e.html" target="_blank">matplotlib使用小結</a>

<a href="http://www.math.ecnu.edu.cn/~latex/" target="_blank">LaTeX科技排版</a>

<a href="http://bbs.ctex.org/viewthread.php?tid=52294" target="_blank">參考文獻自動搜集管理完美攻略(圖文版):Latex+Lyx+Zotero</a>

對數坐标軸

在實際中,我們可能經常會用到對數坐标軸,這時可以用下面的三個函數來實作

ax.semilogx(x,y) #x軸為對數坐标軸

ax.semilogy(x,y) #y軸為對數坐标軸

ax.loglog(x,y) #雙對數坐标軸

因項目需要輸出中文統計圖,選擇matplotlib還不錯。在其中使用中文發現有些問題。在網上找到的解決方案還不錯。

一、找到c:\python24\lib\site-packages\matplotlib\mpl-data\matplotlibrc  (修改font.sans-serif、verbose.level兩行代碼)

1、找到了matplotlibrc設定檔案,是個文本檔案,随便找個編輯器打開它,找到font.sans-serif一行,将後邊直接改成一個nothing;(把 “:”後的“#......”都去掉)

2、找到verbose.level一行,把預設的silent改成debug.

二、找到Vera.ttf,将Vera.ttf用一個中文TrueType文字替換,名字是Vera,字尾是.ttf(True Type Font),即可。

注意:在這裡有兩個地方,C:\Python24\Lib\site-packages\matplotlib\mpl-data\fonts\ttf\下的和C:\Python24\Lib\site-packages\matplotlib\mpl-data\下的兩個vera.ttf檔案。

三、字元串,都用u"..."的形式.(檔案編碼utf-8 加上" # coding = utf-8  "一行.)

若是單獨的畫圖,這裡要注意,将PY檔案用記事本打開,“另存為”,編碼選為“UTF-8”,儲存,即可。

附代碼如下:

1.       # coding = utf-8

2.        from pylab import *

3.        x = [2,4,6,8,10]

4.        y = [1224,838,632,626,624]

5.        xlabel(u"text for x軸")

6.        ylabel(u"text for y軸")

7.        title(u"x軸和Y軸對應關系")

8.        plot(x,y)

9.        savefig('test')

10.    show()

本文轉自 chengxuyonghu 51CTO部落格,原文連結:http://blog.51cto.com/6226001001/1576038,如需轉載請自行聯系原作者