《利用python進行資料分析》讀書筆記--第八章 繪圖和可視化

來源:互聯網
上載者:User

標籤:ant   border   tac   isis   9.png   vertica   修改   ima   char   

http://www.cnblogs.com/batteryhp/p/5025772.html

 

python有許多視覺化檢視,本書主要講解matplotlib。matplotlib是用於建立出版品質圖表的案頭繪圖包(主要是2D方面)。matplotlib的目的是為了構建一個MATLAB式的繪圖介面。本書中的大部分圖都是用它產生的。除了圖形介面顯示,還可以把圖片儲存為pdf、svg、jpg、png、gif等形式。

1、matplotlib API入門

Ipython可以用close()關閉介面。

Figure和Subplot

matplotlib的映像都位於Figure對象中。用plt.figure建立一個新的Figure。

import numpy as npimport pandas as pdimport matplotlib.pyplot as plt‘‘‘#plt.plot(np.arange(10))fig = plt.figure()#plt.show()#figsize 有一些重要的選項,特別是figsize,規定的是圖片儲存到磁碟時具有一定大小的縱橫比。#plt.gcf()即可得到當前Figure的引用ax1 = fig.add_subplot(2,2,1)ax2 = fig.add_subplot(2,2,2)ax3 = fig.add_subplot(2,2,3)plt.plot(np.random.randn(50).cumsum(),‘k--‘)#fig.add_subplot 返回的對象是AxesSubplot對象,下面調用就可以了_ = ax1.hist(np.random.randn(100),bins = 20,color = ‘k‘,alpha = 0.3)ax2.scatter(np.arange(30),np.arange(30) + 3 * np.random.randn(30))plt.show()‘‘‘#由於Figure 和 subplot是一件非常常見的任務,於是出現了更為方便的方法(plt.subplots ),它可以建立一個新的Figure,#並返回一個含有已建立的subplot對象的Numpy數組fig,axes = plt.subplots(2,3)#print figprint axes[0][0]#axes[0][0].hist(np.random.randn(100),bins = 20,color = ‘k‘,alpha = 0.3)plt.show()#這是非常實用的,因為可以輕鬆地對axes數組進行索引,就好像一個是一個二維數組一樣,例如#axes[0,1].還可以通過sharex和sharey指定subplot具有相同的x軸和y軸。在比較相同範圍的資料時,這是#非常實用的,否則matplotlib會自動縮放各圖表的界限。

看一下subplots的作用:

pyplot.subplots的選項還有:

上面的**fig_k可以有很多的參數,文檔中有更多的內容。

調整subplot周圍的間距

預設情況下,matplotlib會在subplot外圍留下一定的邊距,並在subplot之間留下一定的間距。間距和映像的高度和寬度有關,會自動調整。利用Figure的subplots——adjust方法可以修改間距,因此,它是一個頂級函數。

import numpy as npimport pandas as pdimport matplotlib.pyplot as pltsubplots_adjust(left = None,bottom = None,right = None,top = None,wspace = None,hspace = None)#wspace和space用於控制寬度和高度的百分比,可以用做subplot之間的間距,下面是個例子:‘‘‘fig,ax = plt.subplots(2,2,sharex = True,sharey = True)for i in range(2):     for j in range(2):          ax[i,j].hist(np.random.randn(500),bins = 50,color = ‘k‘,alpha = 0.5)plt.subplots_adjust(wspace = 0.5,hspace = 0.5)plt.show()#matplotlib不會檢查標籤的重疊(確實是這樣)。
# -*- encoding: UTF-8 -*- import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfig,ax = plt.subplots(2,2)#cecece是白色……ax[0,0].plot(np.arange(10),linestyle = ‘--‘,color = ‘#CECECE‘)#線上面還可以添加一些標記(marker),以強調實際的資料點。由於matplotlib建立的是連續的線形圖,因此有時可能不太容易看到真實點的位置,標記可以放到格式字串中,但是標記類型和線性必須在顏色的後面ax[0,1].plot(np.random.randn(30).cumsum(),‘ko--‘)ax[1,0].plot(np.random.randn(30).cumsum(),color = ‘k‘,linestyle = ‘--‘,marker = ‘o‘)#線上型圖中,非實際資料點預設是按照線性插值的,可以通過drawstyle選項修改這一點。data = np.random.randn(30).cumsum()ax[1,1].plot(data,‘ko--‘)ax[1,1].plot(data,‘k--‘,drawstyle = ‘steps-post‘)plt.show()

注意上面的drawstyle選項可以規定點與點之間的串連方式,或者說是插值方式,結果為:

設定標題、軸標籤、刻度以及刻度標籤

# -*- encoding: UTF-8 -*- import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport numpy.random as nprfig = plt.figure()ax = fig.add_subplot(1,1,1)ax.plot(npr.randn(1000).cumsum())#要想修改x的刻度,最簡單的方法就是使用set_xticks和set_xticklabels.前者告訴matplotlib將#刻度放在資料範圍中的哪些位置,預設情況下,這些位置就是刻度標籤。但是可以使用set_xticklabels將#任何其他的值用作標籤ticks = ax.set_xticks([0,250,500,700,900,1000])#下面的totation是規定旋轉角度labels = ax.set_xticklabels([‘a‘,‘b‘,‘c‘,‘d‘,‘e‘,‘f‘],rotation = 30,fontsize = ‘small‘)#可以為x軸設定名稱ax.set_xlabel(‘Stages‘)plt.show()

圖例

# -*- encoding: UTF-8 -*- import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport numpy.random as nprfrom datetime import datetime#添加圖例fig = plt.figure()ax = fig.add_subplot(1,1,1)ax.plot(npr.randn(1000).cumsum(),‘k‘,label = ‘one‘)ax.plot(npr.randn(1000).cumsum(),‘k--‘,label = ‘two‘)ax.plot(npr.randn(1000).cumsum(),‘k.‘,label = ‘three‘)ax.legend(loc = ‘best‘)plt.show()

註解與繪圖

# -*- encoding: UTF-8 -*- import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport numpy.random as nprfrom datetime import datetimefig = plt.figure()ax = fig.add_subplot(1,1,1)data = pd.read_csv(‘E:\\spx.csv‘,index_col = 0,parse_dates = True)spx = data[‘SPX‘]spx.plot(ax = ax,style = ‘k-‘)crisis_data = [(datetime(2007,10,11),‘Peak of bull market‘),(datetime(2008,3,12),‘Bear Stearns Fails‘),(datetime(2008,9,15),‘Lehman Bankruptcy‘)]for date,label in crisis_data:    ax.annotate(label,xy = (date,spx.asof(date) + 50),        xytext = (date,spx.asof(date) + 200),        arrowprops = dict(facecolor = ‘black‘),        horizontalalignment = ‘left‘,verticalalignment = ‘top‘)ax.set_xlim([‘1/1/2007‘,‘1/1/2011‘])ax.set_ylim([600,1800])ax.set_title(‘Important dates in 2008-2009 finacial crisis‘)plt.show()#更多關於註解的樣本,請看文檔#圖形的繪製要麻煩些,有一些常見的圖形的對象,這些對象成為塊(patch)#如Rectangle 和 Circle,完整的塊位於matplotlib.patches#要繪製圖形,需要建立一個塊對象shp,然後通過ax.add_patch(shp)將其添加到subplot中fig = plt.figure()ax = fig.add_subplot(1,1,1)rect = plt.Rectangle((0.2,0.75),0.4,0.15,color = ‘k‘,alpha = 0.3)circ = plt.Circle((0.7,0.2),0.15,color = ‘b‘,alpha = 0.3)pgon = plt.Polygon([[0.15,0.15],[0.35,0.4],[0.2,0.6]],color = ‘g‘,alpha = 0.5)ax.add_patch(rect)ax.add_patch(circ)ax.add_patch(pgon)plt.show()

將圖表儲存到檔案

# -*- encoding: UTF-8 -*- import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport numpy.random as nprfrom datetime import datetimefrom io import StringIO#將表徵圖儲存到檔案#savefig函數可以儲存圖形檔案,不同的副檔名儲存為不同的格式fig = plt.figure()ax = fig.add_subplot(1,1,1)rect = plt.Rectangle((0.2,0.75),0.4,0.15,color = ‘k‘,alpha = 0.3)circ = plt.Circle((0.7,0.2),0.15,color = ‘b‘,alpha = 0.3)pgon = plt.Polygon([[0.15,0.15],[0.35,0.4],[0.2,0.6]],color = ‘g‘,alpha = 0.5)ax.add_patch(rect)ax.add_patch(circ)ax.add_patch(pgon)#注意下面的dpi(DPI)和bbox_inches(可以剪除當前表徵圖周圍的空白部分)(確實有效)#plt.savefig(‘pic.jpg‘,dpi = 100,bbox_inches = ‘tight‘)#不一定save到檔案中,也可以寫入任何檔案型對象,比如StringIO:buffer = StringIO()plt.savefig(buffer)plot_data = buffer.getvalue()#這對Web上提供動態產生的圖片是很實用的#plt.show()

savefig的一些選項:

matplotlib配置

matplotlib的一些屬性是可以設定的,比像大小、subplot邊距、色彩配置、字型大小、網格類型等。有兩種方式進行操作。第一種是Python變成方式,即利用rc方法。比如:

plt.rc(‘figure‘,figsize = (10,10))

rc的第一個參數是希望自訂的對象,比如‘figure’、‘axes’、‘xtick’、‘ytick’、‘grid’、‘legend’等。其後可以跟上一系列的關鍵字參數。最簡單的就是寫成一個字典:

font_options = {‘family‘:‘monospace‘,                         ‘weight‘:‘bold‘,                         ‘size‘:‘small‘}plt.rc(‘font‘,**font_options)

matplotlibrc是設定檔,定義好以後每次載入就會用設定的參數。

2、pandas中的繪圖函數

matplotlib是一種比較低級的工具,需要將各種組件組合好:資料展示(線型圖、柱狀圖等)、圖例、標題、刻度標籤以及註解。這是因為製作一張圖表一般需要用到多個對象。在pandas中,會省事不少。pandas能夠利用DataFrame的對象特點建立標準圖表的進階繪圖方法。作者說pandas線上文檔時最好的學習工具,書上的代碼可能過時了。

線型圖

#-*- encoding:utf-8 -*-import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pandas import Series,DataFrames = Series(np.random.randn(10).cumsum(),index = np.arange(0,100,10))#該Series對象的索引會被傳給matplotlib,並繪製X軸。#可以用use_index = False 禁用該功能s.plot(use_index = False)#X軸的刻度和界限可以通過xticks和xlim選項進行調節,Y軸通過xticks和ylim調節plt.show()#pandas的大部分方法都有一個可選的ax參數,可以是一個subplot對象。這可以#使在網格中更為靈活地處理subplot的位置。#DataFrame的plot方法會在一個subplot中為各列繪製線型圖,並自動添加圖例df = DataFrame(np.random.randn(10,4).cumsum(0),    columns = [‘A‘,‘B‘,‘C‘,‘D‘],    index = np.arange(0,100,10))df.plot()plt.show()

下面把參數貼一下:

DataFrame還有一些對列進行處理的參數:

自下面開始就有一些專門的圖形,繪製的時候可以與R語言進行對比:http://www.cnblogs.com/batteryhp/p/4733474.html。

柱狀圖

#-*- encoding:utf-8 -*-import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pandas import Series,DataFrame#產生的線形圖中代碼加上kind = ‘bar’(垂直柱圖) 或者 (水平)kind = ‘barh’(水平柱圖)#Series和DataFrame的索引被用作X(bar)或者Y(barh)的刻度fig,axes = plt.subplots(2,1)data = Series(np.random.randn(16),index = list(‘abcdefghijklmnop‘))data.plot(kind = ‘barh‘,ax = axes[0],color = ‘k‘,alpha = 0.7)data.plot(kind = ‘bar‘,ax = axes[1],color = ‘k‘,alpha = 0.7)#DataFrame會按照行對資料進行分組df = DataFrame(np.random.randn(6,4),index = [‘one‘,‘two‘,‘three‘,‘four‘,‘five‘,‘six‘],    columns = pd.Index([‘A‘,‘B‘,‘C‘,‘D‘],name = ‘Genus‘)) #注意這裡的name會被用作圖例的標題,因為,這本來就是列的名字print dfdf.plot(kind = ‘bar‘)plt.show()#這裡的stacked是標明畫累計柱圖df.plot(kind = ‘bar‘,stacked = True,alpha = 0.5)plt.show()#Series的value_counts可以用來顯示Series中各值的頻數(實驗證明)s = Series([1,2,2,3,4,4,4,5,5,5])s.value_counts().plot(kind = ‘bar‘)plt.show()

下面看一個例子:

#-*- encoding:utf-8 -*-import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pandas import Series,DataFrame#下面是一個例子:做一張堆積柱狀圖來顯示每天各種聚會規模的資料點百分比tips = pd.read_csv(‘E:\\tips.csv‘)party_counts = pd.crosstab(tips.day,tips.size)print party_countsparty_counts = party_counts.ix[:,2:5]#然後進行歸一化是各行和為1party_pcts = party_counts.div(party_counts.sum(1).astype(float),axis = 0)print party_pctsparty_pcts.plot(kind = ‘bar‘,stacked = True)plt.show()

長條圖和密度圖

#-*- encoding:utf-8 -*-import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pandas import Series,DataFrame#繪製小費百分比長條圖tips = pd.read_csv(‘E:\\tips.csv‘)tips[‘tip_pct‘] = tips[‘tip‘] / tips[‘total_bill‘]#bins規定一共分多少個組tips[‘tip_pct‘].hist(bins = 50)plt.show()#與此相關的是密度圖:他是通過計算“可能會產生觀測資料的連續機率分布的估計”#而產生的。一般的過程將該分布金思維一組核(諸如正態之類的較為簡單的分布)。#此時的密度圖稱為KDE圖。kind = ‘kde’即可。tips[‘tip_pct‘].plot(kind = ‘kde‘)plt.show()#顯然,長條圖和密度圖經常會在一起出現comp1 = np.random.normal(0,1,size = 200)comp2 = np.random.normal(10,2,size = 200)values = Series(np.concatenate([comp1,comp2]))print valuesvalues.hist(bins = 100,alpha = 0.3,color = ‘k‘,normed = True)values.plot(kind = ‘kde‘,style = ‘k--‘)plt.show()

散布圖

散布圖(scantter plot)是觀察兩個一維資料序列之間的關係的有效手段。matplotlib中的scantter方法是繪製散布圖的主要方法。

#-*- encoding:utf-8 -*-import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pandas import Series,DataFrame#下面載入macrodata中的資料集,選擇其中幾列並計算對數差macro = pd.read_csv(‘E:\\macrodata.csv‘)data = macro[[‘cpi‘,‘m1‘,‘tbilrate‘,‘unemp‘]]#這裡的diff函數是用來計算相鄰兩數只差,對每一列,後一個數減前一個數trans_data = np.log(data).diff().dropna()#print np.log(data).head()#print np.log(data).diff().head()print trans_data.head()plt.scatter(trans_data[‘m1‘],trans_data[‘unemp‘])plt.title(‘Changes in log %s vs. log %s‘%(‘m1‘,‘unemp‘))plt.show()#畫散布圖矩陣式很有意義的pandas提供了scantter_matrix函數來建立散步矩陣#關於 diagonal 參數,是為了不讓對角線上的圖形(自己和自己的散布圖)顯示為一條直線而設定的關於這種資料的某些圖形顯示#比如 diagonal = ‘kde‘就是畫密度圖且核為kde,若diagonal=‘hist‘,則為長條圖pd.scatter_matrix(trans_data,diagonal = ‘kde‘,color = ‘k‘,alpha = 0.3)pd.scatter_matrix(trans_data,diagonal = ‘hist‘,color = ‘k‘,alpha = 0.3)plt.show()

繪製地圖:圖形化顯示海地地震危機資料

這是一個例子。

#-*- encoding:utf-8 -*-import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom pandas import Series,DataFramefrom mpl_toolkits.basemap import Basemap#下面的例子應該是比較綜合的data = pd.read_csv(‘E:\\Haiti.csv‘)#print data#下面處理一下資料,下面的為日期,緯度、經度#print data[[‘INCIDENT DATE‘,‘LATITUDE‘,‘LONGITUDE‘]][:10]#print data[‘CATEGORY‘][:6]   #這些代表訊息的類型#資料中很有可能有異常值、缺失值,下面看一下#print data.describe()#清除錯誤資訊並移除缺失分類資訊是“一件簡單的事情”data = data[(data.LATITUDE > 18) & (data.LATITUDE < 20) & (data.LONGITUDE > -75) &           (data.LONGITUDE < -70) & data.CATEGORY.notnull()]#我們想根據分類對資料做一些分析或者圖形化工作,但是各個類別欄位中可能含有多個分類。此外,各個分類資訊#不僅有一個編碼,還有一個英語(法語)名稱。因此需要對資料進行規整化處理。下面編寫兩(三)個#函數,一個用於擷取所有分類的列表,一個用於將各個分類資訊拆分為編碼和英語明名稱#sptrip 是刪除空白字元,‘\n‘等;注意作者這種隱式迴圈寫法def to_cat_list(catstr):    stripped = (x.strip() for x in catstr.split(‘,‘))    return [x for x in stripped if x]def get_all_categoties(cat_series):    cat_sets = (set(to_cat_list(x)) for x in cat_series)    return sorted(set.union(*cat_sets))def get_english(cat):    code,names = cat.split(‘.‘)    if ‘|‘ in names:        names = names.split(‘|‘)[1]    return code,names.strip()#下面進行一下ceshi#print get_english(‘2.Urgences logistiques | Vital Lines‘)#接下來做了一個將編碼跟名稱映射起來的字典,這是因為我們等會要用編碼進行分析。#下面將所有組合弄出來all_cats = get_all_categoties(data.CATEGORY)#print data.CATEGORY[:10]#print all_cats#產生器運算式#產生字典english_mapping = dict(get_english(x) for x in all_cats)#print english_mapping[‘2a‘]#print english_mapping[‘6c‘]#根據分類選取記錄的方式有很多,其中之一就是添加指標(或者啞變數)列,每個分類一列。#為此,首先抽取出唯一的分類編碼,並構造一個全零DataFrame(列為分類編碼,索引跟data的索引一樣)def get_code(seq):    return [x.split(‘.‘)[0] for x in seq if x]#下面是將所有的key取出來all_codes = get_code(all_cats)#print all_codescode_index = pd.Index(np.unique(all_codes))#print code_indexdummy_frame = DataFrame(np.zeros((len(data),len(code_index))),index = data.index,columns = code_index)#print len(data)#print dummy_frame.ix[:,:6]#下面將各行中適當的項設定為1,然後再與data進行串連:for row,cat in zip(data.index,data.CATEGORY):    codes = get_code(to_cat_list(cat))    dummy_frame.ix[row,codes] = 1#添加首碼,並且合并一下data = data.join(dummy_frame.add_prefix(‘category_‘))#print data#接下來開始畫圖吧,我們希望把資料繪製在海地的地圖上。basemap資料集是matplotloib的一個外掛程式#使得能夠用Python在地圖上繪製2D資料。basemap提供了許多不同的地球投影以及一種將地球上的經緯度#座標投影轉換為二維matplotlib圖的方式。#“經過一遍又一遍的嘗試”,作者編寫了下面的函數,繪製出一張簡單的黑白地圖。def basic_haiti_map(ax = None,lllat = 17.25,urlat = 20.25,lllon = -75,urlon = -71):    #建立極球面投影的Basemap執行個體。    m  = Basemap(ax = ax,projection = ‘stere‘,        lon_0 = (urlon + lllon) / 2,        lat_0 = (urlat + lllat) / 2,        llcrnrlat = lllat,urcrnrlat = urlat,        llcrnrlon = lllon,urcrnrlon = urlon,        resolution = ‘f‘ )

由於window下安裝geos不成功,這部分等ubuntu裝好了再接著寫。

4、Python圖形化工具生態系統

介紹幾個其他的繪圖工具。

Chaco

特點:靜態圖 + 互動圖形,非常適合用複雜的圖形化方法表示資料的內部關係。對互動支援的好的多,互動式GUI是個不錯選擇。

mayavi

這是一個基於開源C++圖形庫VTK的3D圖形工具包。可以整合到Ipython互動使用。

其他庫

其他庫或者應用還有:PyQwt、Veusz、gnuplotpy、biggles等,大部庫都在向基於Web的技術發展,並逐漸遠離案頭圖形技術。

圖形化工具的未來

基於Web技術(如Javascript)的圖形化是必然的發展趨勢,現在已經有不少了,higncharts等。

 

《利用python進行資料分析》讀書筆記--第八章 繪圖和可視化

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.