http://www.cnblogs.com/batteryhp/p/5025772.htmlhtml
python有許多可視化工具,本書主要講解matplotlib。matplotlib是用於建立出版質量圖表的桌面繪圖包(主要是2D方面)。matplotlib的目的是爲了構建一個MATLAB式的繪圖接口。本書中的大部分圖都是用它生成的。除了圖形界面顯示,還能夠把圖片保存爲pdf、svg、jpg、png、gif等形式。python
一、matplotlib API入門ubuntu
Ipython能夠用close()關閉界面。數組
Figure和Subplotapp
matplotlib的圖像都位於Figure對象中。用plt.figure建立一個新的Figure。dom
import numpy as np import pandas as pd import 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 fig print 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的做用:svg
pyplot.subplots的選項還有:函數
上面的**fig_k能夠有不少的參數,文檔中有更多的內容。工具
調整subplot周圍的間距post
默認狀況下,matplotlib會在subplot外圍留下必定的邊距,並在subplot之間留下必定的間距。間距和圖像的高度和寬度有關,會自動調整。利用Figure的subplots——adjust方法能夠修改間距,所以,它是一個頂級函數。
import numpy as np import pandas as pd import matplotlib.pyplot as plt subplots_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 np import pandas as pd import matplotlib.pyplot as plt fig,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 np import pandas as pd import matplotlib.pyplot as plt import numpy.random as npr fig = 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 np import pandas as pd import matplotlib.pyplot as plt import numpy.random as npr from 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 np import pandas as pd import matplotlib.pyplot as plt import numpy.random as npr from datetime import datetime fig = 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 np import pandas as pd import matplotlib.pyplot as plt import numpy.random as npr from datetime import datetime from 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(每英寸點數)和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是配置文件,定義好之後每次加載就會用設置的參數。
二、pandas中的繪圖函數
matplotlib是一種比較低級的工具,須要將各類組件組合好:數據展現(線型圖、柱狀圖等)、圖例、標題、刻度標籤以及註解。這是由於製做一張圖表通常須要用到多個對象。在pandas中,會省事很多。pandas可以利用DataFrame的對象特色建立標準圖表的高級繪圖方法。做者說pandas在線文檔時最好的學習工具,書上的代碼可能過期了。
線型圖
#-*- encoding:utf-8 -*- import numpy as np import pandas as pd import matplotlib.pyplot as plt from pandas import Series,DataFrame s = 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 np import pandas as pd import matplotlib.pyplot as plt from 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 df df.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 np import pandas as pd import matplotlib.pyplot as plt from pandas import Series,DataFrame #下面是一個例子:作一張堆積柱狀圖來顯示天天各類聚會規模的數據點百分比 tips = pd.read_csv('E:\\tips.csv') party_counts = pd.crosstab(tips.day,tips.size) print party_counts party_counts = party_counts.ix[:,2:5] #而後進行歸一化是各行和爲1 party_pcts = party_counts.div(party_counts.sum(1).astype(float),axis = 0) print party_pcts party_pcts.plot(kind = 'bar',stacked = True) plt.show()
直方圖和密度圖
#-*- encoding:utf-8 -*- import numpy as np import pandas as pd import matplotlib.pyplot as plt from 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 values values.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 np import pandas as pd import matplotlib.pyplot as plt from 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 np import pandas as pd import matplotlib.pyplot as plt from pandas import Series,DataFrame from 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_codes code_index = pd.Index(np.unique(all_codes)) #print code_index dummy_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裝好了再接着寫。
四、Python圖形化工具生態系統
介紹幾個其餘的繪圖工具。
Chaco
特色:靜態圖 + 交互圖形,很是適合用複雜的圖形化方法表示數據的內部關係。對交互支持的好的多,交互式GUI是個不錯選擇。
mayavi
這是一個基於開源C++圖形庫VTK的3D圖形工具包。能夠集成到Ipython交互使用。
其餘庫
其餘庫或者應用還有:PyQwt、Veusz、gnuplotpy、biggles等,大部庫都在向基於Web的技術發展,並逐漸遠離桌面圖形技術。
圖形化工具的將來
基於Web技術(如Javascript)的圖形化是必然的發展趨勢,如今已經有很多了,higncharts等。