python自定义函数画图_利用Python绘图和可视化(长文慎入)
Python有許多可視化工具,但是我主要講解matplotlib(http://matplotlib.sourceforge.net)。此外,還可以利用諸如d3.js(http://d3js.org/)之類的工具為Web應(yīng)用構(gòu)建交互式圖像。
matplotlib是一個用于創(chuàng)建出版質(zhì)量圖表的桌面繪圖包(主要是2D方面)。該項目是由John Hunter于2002年啟動的,其目的是為Python構(gòu)建一個MATLAB式的繪圖接口。如果結(jié)合使用一種GUI工具包(如IPython),matplotlib還具有諸如縮放和平移等交互功能。它不僅支持各種操作系統(tǒng)上許多不同的GUI后端,而且還能將圖片導(dǎo)出為各種常見的矢量(vector)和光柵(raster)圖:PDF、SVG、JPG、PNG、BMP、GIF等。
matplotlib還有許多插件工具集,如用于3D圖形的mplot3d以及用于地圖和投影的basemap。要使用本章中的代碼示例,請確保你的IPython是以Pylab模式啟動的(ipython --pylab),或通過%gui魔術(shù)命令打開了GUI事件循環(huán)集成。
1、matplotlib API入門
使用matplotlib的辦法有很多種,最常用的方式是Python模式的IPython(ipython -pylab)。這樣會將IPython配置為使用你所指定的matplotlib GUI后端(Tk、wxPython、PyQt、Mac OS X native、GTK)。對大部分用戶而言,默認的后端就已經(jīng)夠用了。Pylab模式還會向IPython引入一大堆模塊和函數(shù)以提供一種更接近于MATLAB的界面。繪制一張簡單的圖表即可測試是否一切準(zhǔn)備就緒:
如果一切都沒有問題,就會彈出一個新窗口,其中繪制的是一條直線。你可以用鼠標(biāo)或輸入close()來關(guān)閉它。matplotlib API函數(shù)(如plot和close)都位于matplotlib.pyllot模塊中,其通常的引入約定是:
雖然pandas的繪圖函數(shù)能夠處理許多普通的繪圖任務(wù),但如果需要自定義一些高級功能的話就必須學(xué)習(xí)matplotlib API。matplotlib的示例庫和文檔是成為繪圖高手的最佳學(xué)習(xí)資源。
2、Figure和Subplot
matplotlib的圖像都位于Figure對象中。你可以用plt.figure創(chuàng)建一個新的Figure:
這時會彈出一個空窗口。plt.figure有一些選項,特別是figsize,它用于確保當(dāng)圖片保存到磁盤時具有一定的大小和縱橫比。matplotlib中的Figure還支持一種MATLAB式的編號架構(gòu)(如plt.figure(2))。通過plt.gcf()即可得到當(dāng)前Figure的引用。
不能通過空Figure繪圖。必須用add_subplot創(chuàng)建一個或多個subplot才行:
這條代碼的意思是:圖像應(yīng)該是22的,且當(dāng)前選中的是4個subplot中的第一個(編號從1開始)。如果再把后面兩個subplot也創(chuàng)建出來,最終得到的圖像如下所示:
如果這時發(fā)出一條繪圖命令哪個(如plt.plot([1.5, 3.5, -2, 1.6])),matplotlib就會在最后一個用過的subplot(如果沒有則創(chuàng)建一個)上進行繪制。因此,如果我們執(zhí)行下列命令,你就會得到如下所示的效果:
“k--”是一個線型選項,用于告訴matplotlib繪制黑色虛線圖。上面那些由fig.add_subplot所返回的對象是AxesSubplot對象,直接調(diào)用它們的實例方法就可以在其他空著的格子里面畫圖了,如下所示:
你可以在matplotlib的文檔中找到各種圖標(biāo)類型。由于根據(jù)特定布局創(chuàng)建Figure和subplot是一件非常常見的任務(wù),于是便出現(xiàn)了一個更為方便的方法(plt.subplots),它可以創(chuàng)建一個新的Figure,并返回一個含有已創(chuàng)建的subplot對象的NumPy數(shù)組:
這是非常實用的,因為可以輕松地對axes數(shù)組進行索引,就好像是一個二維數(shù)組一樣,例如,axes[0, 1]。你還可以通過sharex和sharey指定subplot應(yīng)該具有相同的X軸或Y軸。在比較相同范圍的數(shù)據(jù)時,這也是非常實用的,否則,matplotlib會自動縮放各圖表的界限。
3、調(diào)整subplot周圍的間距
默認情況下,matplotlib會在subplot外圍留下一定的邊距,并在subplot之間留下一定的間距。間距跟圖像的高度和寬度有關(guān),因此,如果你調(diào)整了圖像的大小(不管是編程還是手工),間距也會自動調(diào)整。利用Figure的subplots_adjust方法可以輕而易舉地修改間距,此外,它也是個頂級函數(shù):
wspace和hspace用于控制寬度和高度的百分比,可以用作subplot之間的間距。下面是一個簡單的例子,我們將間距收縮到了0:
不難看出,其中的軸標(biāo)簽重疊了。matplotlib不會檢查標(biāo)簽是否重疊,所以對于這種情況,你只能自己設(shè)定刻度位置和刻度標(biāo)簽。
4、顏色、標(biāo)記和線型
matplotlib的plot函數(shù)接受一組X和Y坐標(biāo),還可以接受一個表示顏色和線型的字符串縮寫。例如,要根據(jù)x和y繪制綠色虛線,你可以執(zhí)行如下代碼:
這種在一個字符串中指定顏色和線型的方式非常方便。通過下面這種更為明確的方式也能得到同樣的效果:
常用的顏色都有一個縮寫詞,要使用其他任意顏色則可以通過指定其RGB值的形式使用(例如,'#CECECE')。完整的linestyle列表請參見plot的文檔。
線型圖還可以加上一些標(biāo)記(marker),以強調(diào)實際的數(shù)據(jù)點。由于matplotlib創(chuàng)建的是連續(xù)的線型圖(點與點之間插值),因此有時可能不太容易看出真實數(shù)據(jù)點的位置。標(biāo)記也可以放到格式字符串中,但標(biāo)記類型和線型必須放在顏色后面。
還可以將其寫成更為明確的形式:
在線型圖中,非實際數(shù)據(jù)點默認是按線性方式插值的。可以通過drawstyle選項修改:
5、刻度、標(biāo)簽和圖例
對于大多數(shù)的圖表裝飾項,其主要實現(xiàn)方式有二:使用過程型的pyplot接口以及更為面向?qū)ο蟮脑鷐atplotlib API。pyplot接口的設(shè)計目的就是交互式作用,含有諸如xlim、xticks和xticklabels之類的方法。它們分別控制圖表的范圍、刻度位置、刻度標(biāo)簽等。其使用方式有以下兩種:
調(diào)用時不帶參數(shù),則返回當(dāng)前的參數(shù)值。例如,plt.xlim()返回當(dāng)前的X軸繪圖范圍。
調(diào)用時帶參數(shù),則設(shè)置參數(shù)值。因此,plt.xlim([0, 10])會將X軸的范圍設(shè)置為0到10。
所有這些方法都是對當(dāng)前或最近創(chuàng)建的AxesSubplot起作用的。它們各自對應(yīng)subplot對象上的兩個方法,以xlim為例,就是ax.get_xlim和ax.set_xlim。我更喜歡使用subplot的實例方法,當(dāng)然你完全可以選擇自己覺得方便的那個。
(1)設(shè)置標(biāo)題、軸標(biāo)簽、刻度以及刻度標(biāo)簽
為了說明軸的自定義,我將創(chuàng)建一個簡單的圖像并繪制一段隨機漫步:
要修改X軸的刻度,最簡單的辦法是使用set_xticks和set_xticklabels。前者告訴matplotlib要將刻度放在數(shù)據(jù)范圍中的哪些位置,默認情況下,這些位置也就是刻度標(biāo)簽。但我們可以通過set_xticklabels將任何其他的值用作標(biāo)簽:
說明:
Y軸的修改方式與此類似,只需將上述代碼中的x替換為y即可。
(2)添加圖例
圖例(legend)是另一種用于標(biāo)識圖表元素的重要工具。添加圖例的方式有二。最簡單的是在添加subplot的時候傳入label參數(shù):
在此之后,你可以調(diào)用ax.legend()或plt.legend()來自動創(chuàng)建圖例:
loc告訴matplotlib要將圖例放在哪。如果你不是吹毛求疵的話,“best”是不錯的選擇,因為它會選擇最不礙事的位置。要從圖例中去除一個或多個元素,不傳入label或傳入label='_nolegend_'即可。
6、注釋以及在Subplot上繪圖
除標(biāo)準(zhǔn)的圖表對象之外,你可能還希望繪制一些自定義的注釋(比如文本、箭頭或其他圖形等)。
注釋可以通過text、arrow和annotate等函數(shù)進行添加。text可以將文本繪制在圖表的指定坐標(biāo)(x, y),還可以加上一些自定義格式:
In [41]: ax.text(x, y, ‘Hello world!‘,family=‘monospace‘, fontsize=10)
注解中可以既含有文本也含有箭頭。例如,我們根據(jù)2007年以來的標(biāo)準(zhǔn)普爾500指數(shù)收盤價格(來自Yahoo! Finance)繪制一張曲線圖,并標(biāo)出2008年到2009年金融危機期間的一些重要日期。如下所示:
圖像的繪制要麻煩一些。matplotlib有一些表示常見圖形的對象。這些對象被稱為塊(patch)。其中有些可以在matplotlib.pyplot中找到(如Rectangle和Circle),但完整集合位于matplotlib.patches。
要在圖表中添加一個圖形,你需要創(chuàng)建一個塊對象shp,然后通過ax.add_patch(shp)將其添加到subplot中。
說明:
如果查看許多常見圖表對象的具體實現(xiàn)代碼,你就會發(fā)現(xiàn)它們其實就是由塊組裝而成的。
7、將圖表保存到文件
利用plt.savefig可以將當(dāng)前圖表保存到文件。該方法相當(dāng)于Figure對象的實例方法savefig。例如,要將圖表保存為SVG文件,你只需輸入:
In [42]: plt.savefig(‘figpath.svg‘)
文件類型是通過文件擴展名推斷出來的。因此,如果你使用的是.gif,就會得到一個PDF文件。我在發(fā)布圖片時最常用到兩個重要的選項是dpi(控制“每英寸點數(shù)”分辨率)和bbox_inches(可以翦除當(dāng)前圖表周圍的空白部分)。要得到一張帶有最小白邊且分辨率為400DPI的PNG圖片,你只需輸入:
In [43]: plt.savefig(‘figpath.svg‘, dpi=400, bbox_inches=‘tight‘)
savefig并非一定要寫入磁盤,也可以寫入任何文件型的對象,比如StringIO:
這對在Web上提供動態(tài)生成的圖片是很實用的。Figure.savefig方法的參數(shù)及說明如下所示:
8、matplotlib配置
matplotlib自帶一些配色方案,以及為生成出版質(zhì)量的圖片而設(shè)定的默認配置信息。幸運的是,幾乎所有默認行為都能通過一組全局參數(shù)進行自定義,它們可以管理圖像大小、subplot邊距、配色方案、字體大小、網(wǎng)格類型等。操作matplotlib配置系統(tǒng)的方式主要有兩種。第一種是Python編程方式,即利用rc方法。比如說,要將全局的圖像默認大小設(shè)置為10bubuko.com,布布扣10,你可以執(zhí)行:
In [45]: plt.rc(‘figure‘, figsize=(10, 10))
rc的第一個參數(shù)是希望自定義的對象,如‘figure’、‘a(chǎn)xes’、‘xtick’、‘ytick’、‘grid’、‘legend’等。其后可以跟上一系列的關(guān)鍵字參數(shù)。最簡單的辦法是將這些選項寫成一個字典:
In [46]: font_options = {‘family‘ : ‘monospace‘, ‘weight‘ : ‘bold‘, ‘size‘ : ‘small‘}
In [47]: plt.rc(‘font‘, **font_options)
要了解全部的自定義選項,請查閱matplotlib的配置文件matplotlibrc(位于matplotlib/mpl-data目錄中)。如果對該文件進行了自定義,并將其放在你自己的.matplotlib目錄中,則每次使用matplotlib時就會加載該文件。
9、pandas中的繪圖函數(shù)
不難看出,matplotlib實際上是一種比較低級的工具。要組裝一張圖表,你得用它的各種基礎(chǔ)組件才行:數(shù)據(jù)顯示(即圖表類型:線型圖、柱狀圖、盒形圖、散布圖、等值線圖等)、圖例、標(biāo)題、刻度標(biāo)簽以及其他注解型信息。這是因為要根據(jù)數(shù)據(jù)制作一張完整圖表通常都需要用到多個對象。在pandas中,我們有行標(biāo)簽、列標(biāo)簽以及分組信息(可能有)。這也就是說,要制作一張完整的圖表,原本需要一大堆的matplotlib代碼,現(xiàn)在只需要一兩條簡潔的語句就可以了。pandas有許多能夠利用DataFrame對象數(shù)組組織特點來創(chuàng)建標(biāo)準(zhǔn)圖表的高級繪圖方法(這些函數(shù)的數(shù)量還在不斷增加)。
10、線型圖
Series和DataFrame都有一個用于生成各類圖表的plot方法。默認情況下,它們所生成的是線型圖:
該Series對象的索引會被傳給matplotlib,并用以繪制X軸。可以通過use_index=False禁用該功能。X軸的刻度和界限可以通過xticks和xlim選項進行調(diào)節(jié),Y軸就用yticks和ylim。plot參數(shù)的完整列表如下所示:
pandas的大部分繪圖方法都有一個可選的ax參數(shù),它可以是一個matplotlib的subplot對象。這使你能夠在網(wǎng)格布局中更為靈活地處理subplot的位置。
DataFrame的plot方法會在一個subplot中為各列繪制一條線,并自動創(chuàng)建圖例,如下所示:
注意:
plot的其他關(guān)鍵字參數(shù)會被傳給相應(yīng)的matplotlib繪圖函數(shù),所以要更深入地自定義圖表,就必須學(xué)習(xí)更多有關(guān)matplotlib API的知識。
DataFrame還有一些用于對列進行靈活處理的選項,例如,是要將所有列都繪制到一個subplot中還是創(chuàng)建各自的subplot,詳細信息如下所示:
11、柱狀圖
在生成線型圖的代碼中加上kind=‘bar‘(垂直柱狀圖)或kind=‘barh‘(水平柱狀圖)即可生成柱狀圖。這時,Series和DataFrame的索引將會被用作X(bar)或Y(barh)刻度,如下所示:
對于DataFrame,柱狀圖會將每一行的值分為一組,如下所示:
DataFrame各列的名稱“Genus”被用作了圖例的標(biāo)題。設(shè)置stacked=True即可為DataFrame生成堆積柱狀圖,這樣每行的值就會被堆積在一起,如下所示:
In [62]: df.plot(kind=‘bar‘, stacked=True, alpla=0.5)
注意:
柱狀圖有一個非常不錯的用法:利用value_counts圖形化顯示Series中各值的出現(xiàn)頻率,比如s.value_counts().plot(kind=‘bar‘)。
以小費數(shù)據(jù)集為例,假設(shè)我們想要做一張堆積柱狀圖以展示每天各種聚會規(guī)模的數(shù)據(jù)點的百分比。我用read_csv將數(shù)據(jù)加載進來,然后根據(jù)日期和聚會規(guī)模創(chuàng)建一張交叉表:
小費數(shù)據(jù)集:http://download.csdn.net/detail/shengshengwang/7197845
然后進行規(guī)格化,使得各行的和為1(必須轉(zhuǎn)換成浮點數(shù),以避免Python 2.7中的整數(shù)除法問題),并生成圖表,如下所示:
說明:
通過該數(shù)據(jù)集可以看出,聚會規(guī)模在周末就會變大。
12、直方圖和密度圖
直方圖(histogram)是一種可以對值頻率進行離散化顯示的柱狀圖。數(shù)據(jù)點被拆分到離散的、間隔均勻的面元中,繪制的是各面元中數(shù)據(jù)點的數(shù)量。再以前面那個小費數(shù)據(jù)為例,通過Series的hist方法,我們可以生成一張“小費占消費總額百分比”的直方圖。In [71]: tips[‘tip_pct‘] = tips[‘tip‘] / tips[‘total_bill‘]
In [72]: tips[‘tip_pct‘].hist(bins=50)
與此相關(guān)的一種圖表類型是密度圖,它是通過計算“可能會產(chǎn)生觀測數(shù)據(jù)的連續(xù)概率分布的估計”而產(chǎn)生的。一般的過程是將該分布近似為一組核(即諸如正態(tài)(高斯)分布之類的較為簡單的分布)。因此,密度圖也被稱作KDE(Kernel Density Estimate,核密度估計),如下所示:
In [73]: tips[‘tip_pct‘].plot(kind=‘kde‘)
這兩種圖表常常會被畫在一起。直方圖以規(guī)格化形式給出(以便給出面元化密度),然后再在其上繪制核密度估計。接下來來看一個由兩個不同的標(biāo)準(zhǔn)正態(tài)分布組成的雙峰分布,如下所示:
13、散布圖
散布圖(scatter plot)是觀察兩個一維數(shù)組序列之間的關(guān)系的有效手段。matplotlib的scatter方法是繪制散布圖的主要方法。在下面這個例子中,我加載了來自statsmodels項目的macrodata數(shù)據(jù)集,選擇其中幾列,然后計算對數(shù)差:
macrodata數(shù)據(jù)集:http://download.csdn.net/detail/shengshengwang/7198003
在探索式數(shù)據(jù)分析中,同時觀察一組變量的散布圖是很有意義的,這也被稱為散布圖矩陣(scatter plot matrix)。純手工創(chuàng)建這樣的圖表很費工夫,所以pandas提供了一個能從DataFrame創(chuàng)建散布圖矩陣的scatter_matrix函數(shù)。它還支持在對角線上放置各變量的直方圖或密度圖。如下所示:
In [85]: scatter_matrix(trans_data, diagonal=‘kde‘, color=‘k‘, alpha=0.3
14、Python圖形化工具生態(tài)系統(tǒng)
(1)Chaco
Chaco(http://code.enthought.com/chaco/)是由Enthought開發(fā)的一個繪圖工具包,它既可以繪制靜態(tài)圖又可以生成交互式圖形。它非常適合用復(fù)雜的圖形化方式表達數(shù)據(jù)的內(nèi)部關(guān)系。跟matplotlib相比,Chaco對交互的支持要好得多,而且渲染速度很快。如果要創(chuàng)建交互式的GUI應(yīng)用程序,它確實是個不錯的選擇。
(2)mayavi
mayavi項目是一個基于開源C++圖形庫VKT的3D圖形工具包。跟matplotlib一樣,mayavi也能集成到IPython以實現(xiàn)交互式使用。通過鼠標(biāo)和鍵盤進行操作,圖形可以被平移、旋轉(zhuǎn)、縮放。我相信它能成為WebGL(以及相關(guān)產(chǎn)品)的替代品,雖然其生成的圖形很難以交互的形式共享。
(3)其他庫
當(dāng)然,Python領(lǐng)域中還有許多其他的圖形化庫和應(yīng)用程序:PyQwt、Veusz、gnuplotpy、biggles等。我就曾經(jīng)見過PyQwt被用在基于Qt框架(PyQt)的GUI應(yīng)用程序中。許多庫都還在不斷地發(fā)展(有些已經(jīng)被用在大型應(yīng)用程序當(dāng)中了)。近幾年來,我發(fā)現(xiàn)了一個總體趨勢:大部分庫都在向基于Web的技術(shù)發(fā)展,并逐漸遠離桌面圖形技術(shù)。
(4)basemap工具集(http://matplotlib.github.com/basemap,matplotlib的一個插件)使得我們能夠用Python在地圖上繪制2D數(shù)據(jù)。basemap提供了許多不同的地球投影以及一種將地球上的經(jīng)緯度坐標(biāo)投影轉(zhuǎn)換為二維matplotlib圖的方式。
(5)圖形化工具的未來
基于Web技術(shù)(比如JavaScript)的圖形化是必然的發(fā)展趨勢。毫無疑問,許多基于Flash或JavaScript的靜態(tài)或交互式圖形化工具已經(jīng)出現(xiàn)了很多年,而且類似的新工具包(如d3.js及其分支項目)一直都在不斷涌現(xiàn)。相比之下,非Web式的圖形化開發(fā)工作在近幾年中減慢了許多。Python以及其他數(shù)據(jù)分析和統(tǒng)計計算環(huán)境(如R)都是如此。于是,開發(fā)方向就變成了實現(xiàn)數(shù)據(jù)分析和準(zhǔn)備工具(如pandas)與Web瀏覽器之間更為緊密的集成。
end
原文鏈接:http://blog.csdn.net/ssw_1990/article/details/23739953
總結(jié)
以上是生活随笔為你收集整理的python自定义函数画图_利用Python绘图和可视化(长文慎入)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 下载网页文件_『如何用py
- 下一篇: python制作英语字典_如何在Pyth