這裡只講資料分析常用的圖形繪製,至於複雜的圖形不在本篇討論範圍,講到的幾個圖形基本滿足資料分析過程的要求,至於彙報材料或者其他的高品質圖形,以後再另外寫關於ggplot2的簡單使用。
python的繪圖工具主要是matplotlib,這裡不講複雜的使用,只講簡單的使用。
使用matplotlib繪圖有兩種方法:
1.matplotlib繪圖,指定參數data=DataFrame或Series
2.pandas對DataFrame和Series做了處理,它們本身有plot的方法
1.使用matplotlib繪圖,如果用過MATLAB的朋友對這個不陌生。
import pandas as pd import numpy as npimport matplotlib.pyplot as pltfrom pandas import DataFrame, Seriesfrom numpy.random import randn,randimport matplotlib as mplfrom matplotlib.pyplot import savefigmpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定預設字型mpl.rcParams['axes.unicode_minus'] = False # 解決儲存映像是負號'-'顯示為方塊的問題
# 1.先建立一個畫布fig = plt.figure()# 2.然後建立圖形矩陣ax1 = fig.add_subplot(2,2,1)ax2 = fig.add_subplot(2,2,2)ax3 = fig.add_subplot(2,2,3)# 3.查看畫布fig# 4.單獨繪製曲線plt.plot(randn(50).cumsum(), 'k--')# 5.在剛才建立的圖形矩陣上畫圖# 5.1.長條圖ax1.hist(randn(100), bins = 20, color = 'k', alpha = 0.3)# 5.2.散佈圖ax2.scatter(np.arange(30), np.arange(30)+3*randn(30))# 5.3.線圖(預設)ax3.plot(randn(50).cumsum(),'k--')# 6.將畫好的圖形顯示出來fig# 或者plt.show()
前面的代碼是先建立畫布然後建立圖形矩陣,有人嫌麻煩,於是有了下面的代碼。
# 建立圖形矩陣的快捷函數# sharex,sharey 共用x,y軸,也就是刻度標記是一樣的fig, axes = plt.subplots(2,2, sharex = True, sharey = True)for i in range(2): for j in range(2): axes[i,j].hist(randn(500), bins=50, color='k', alpha = 0.5)plt.subplots_adjust(wspace = 0,hspace=0)fig
# 圖形的屬性1.color:顏色1.1 r:紅色1.2 b:藍色1.3 g:綠色1.3 y:黃色2.資料標記markder2.1 o:圓圈2.2 .:圓點2.2 d:棱形3.線型linestyle3.1 沒有參數的話就是預設畫點圖3.2 --:虛線3.3 -:實線4.透明度alpha5.大小size6.網格線plt.grid(True,color='g',linestyle='-',linewidth='2')
# 地區填充import matplotlib.pyplot as pltimport numpy as npx=np.linspace(0,5*np.pi,1000)y1=np.sin(x)y2=np.sin(2*x)plt.plot(x,y1)plt.plot(x,y2)# 填充plt.fill(x,y1,'b',alpha=0.3)plt.fill(x,y2,'r',alpha=0.3)# 只填充相交地區fig=plt.figure()ax=plt.gca()ax.plt(x,y1,x,y2,color='black')ax.fill_between(x,y1,y2,facecolor='blue')ax.fill_between(x,y1,y2,where=y1>y2,facecolor='yellow',interpolate=True)ax.fill_between(x,y1,y2,where=y2>y1,facecolor='green',interpolate=True)plt.show()
# 樣式plt.style.use('ggplot')# 列印plt支援的樣式print(plt.style.available)
# 長條圖與二維長條圖# 使用plt方式import numpy as npimport matplotlib.pyplot as plt# normed 標準化指定是顯示頻率還是頻數mu = 100sigma = 20x = mu + sigma * np.random.randn(2000)plt.hist(x, bins=10,color='red',normed=True)plt.hist(x, bins=50,color='green',normed=False)plt.show()# 二維長條圖x = np.random.randn(1000)+2y = np.random.randn(1000)+3plt.hist2d(x, y, bins=40)plt.show()
# 積分圖# 其實是繪製多邊形圖實現積分圖import matplotlib.pyplot as pltfrom matplotlib.patches import Polygon #多邊形import numpy as npdef func(x): return -(x-2)*(x-8)+40x=np.linspace(0,10)y=func(x)fig.ax=plt.subplot()plt.plot(x,y,'r',linewidth=2)a,b=2,9ax.set_xticks([a,b])# ax.set_yticks([])ax.set_xticklabels(['$a$','$b$'])# 繪製積分地區的多邊形點位置ix=np.linspace(a,b)iy=func(ix)ixy=zip(ix,iy)verts=[(a,0)]+list(ixy)+[(b,0)]poly=Ploygen(verts,facecolor='0.9',egdcolor='0.1')ax.add_patch(poly)plt.figtext(0.9,0.05,'$x$')plt.figtext(0.1,0.9,'$y$')x_mathch=(a+b)*0.4y_match=30plt.text(x_match,y_match, r'$inta^b (-(x-2)*(x-8)+40)dx$',fontsize=20)plt.show()
# 公式import matplotlib.pyplot as pltfig=plt.figure()ax=fig.add_subplot(111)ax.set_xlim(1,7)ax.set_ylim(1,5)ax.text(2,4,r"$ \alpha_i \pi \lambda \omega $", size=25)plt.show()
plt.plot(randn(30).cumsum(),'b.--')
# 設定標題,軸刻度,軸標籤,以及刻度標籤fig = plt.figure()ax = fig.add_subplot(1,1,1)ax.plot(randn(1000).cumsum())ticks = ax.set_xticks([0,250,500,750,1000]) #x軸刻度labels = ax.set_xticklabels(['one','tow','three','four','five'], rotation=30, fontsize='small') #x軸刻度名稱ax.set_title('my first matplotlib plot') #標題ax.set_xlabel('stages') #x軸標題fig# 添加圖例# 也是在同一幅圖中繪製多條線的方法fig = plt.figure()ax = fig.add_subplot(1,1,1)ax.plot(randn(1000).cumsum(), 'k',label='one')ax.plot(randn(1000).cumsum(),'k--', label='two')ax.plot(randn(1000).cumsum(), 'k.',label = 'three')# 圖例放置的位置ax.legend(loc='best')# ax.legend(loc=1) # 1,2,3,4表示圖的4個角落fig# 儲存圖片fig.savefig('pd_fig.png')# 註解,以及subplot上繪圖from datetime import datetimedata = pd.read_csv('spx.csv',index_col = 0,parse_dates=True)spx=data['SPX']data.columnsdata.head()fig=plt.figure()ax = fig.add_subplot(1,1,1)spx.plot(ax=ax, style='k--')crisis_data=[ (datetime(2007,10,11),'peak of bull market'), (datetime(2008,3,12),'bear strarns fails'), (datetime(2008,9,15),'lehman bankruptcy')]for date,label in crisis_data: ax.annotate(label, xy=(data,spx.asof(date)+50), xytext=(date,spx.asof(date)+200), arrowprops=dict(facecolor='black'), verticalalignment='top')# 軸刻度範圍ax.set_xlim(['1/1/2007','1/1/2011'])ax.set_ylim([600,800])ax.set_title('import dates in 2008-2009 financial crisis')fig
批量儲存圖片
如果只有一張圖片,這沒什麼好說的,但是如果要對每個維度繪圖,然後儲存圖片呢。
下面的批量儲存的虛擬碼
for _ in all_need_plot: fig = plt.figure() ax=fig.add_subplot(111) sub_data[years].plot(ax=ax, style='o-',title='%s 月銷量趨勢圖'%lev3) file = r'E:\服裝預測\銷量趨勢-%s.jpg' %lev3 savefig(file) time.sleep(0.5) # 注意這裡要暫停一下,不然會出問題的 plt.close() # 最後記得關閉控制代碼,再畫下一張圖
前面說過,既可以用matplotlib來繪圖,Series和DataFrame本身也封裝有繪圖的函數。下面是一些常用的圖形。
| 作圖函數名 |
功能 |
模組 |
| plot() |
折線圖,點圖 |
matplotlib 和 pandas |
| pie() |
餅圖 |
matplotlib 和 pandas |
| hist() |
長條圖,橫條圖 |
matplotlib 和 pandas |
| boxplot() |
盒狀圖 |
pandas |
| plot(loyg=True) |
y軸的對數圖形 |
pandas |
| plot(yerr=True) |
誤差橫條圖 |
pandas |
pandas簡單畫圖
# 1.matplotlib的方法import matplotlib.pyplot as pltplt.plot(x,y,S)# S是圖形選項,包括顏色,樣式,圖形的類型,具體的參數和前面的一樣。# 2.pandas的方法D.plot(kind='圖形類型')# D是DataFrame或者Series,預設以index為橫座標,# 每列資料為縱座標自動繪圖,也就是每列資料繪製一個圖形。# kind=# line :線# bar :橫條圖# barh,hist :長條圖# box :盒狀圖# kde :密度圖# area :面積圖# pie :餅圖# 除了kind參數外,也能接受plt.plot()中的參數。
常用的圖形
# 1.線形圖(預設)s = Series(randn(10).cumsum(), index=np.arange(0,100,10))s.plot(style='ko--')#如果是資料框,則每一列畫一條線df = DataFrame(randn(10,4).cumsum(0),columns=['a','b','c','d'],index=np.arange(0,100,10))df.plot()# 2.柱狀圖# 柱狀圖是對每一個數字畫圖,如果有多個數字就畫多條柱子# 也就是說,柱狀圖需要給定柱子的高度。注意這和長條圖是不一樣的,# 長條圖會自己計數,然後繪圖,如果畫得比較細,就是密度曲線了fig,axes = plt.subplots(2,1)data = Series(np.random.rand(16),index=list('abcdefghijklmnop'))data.plot(kind='bar',ax=axes[0])data.plot(kind='bar',ax=axes[1])figdf = DataFrame(np.random.rand(6,4), index='one','two','three','four','five','six'], name='Genus'))df# 每行畫一個族柱,有多少行就有多少族柱df.plot(kind='bar')# 2.2堆積的柱狀圖df.plot(kind='bar',stacked=True,alpha=0.5)tips = pd.read_csv('tips.csv')tips.head()party_counts=pd.crosstab(tips.size,tips.day)party_countsparty_pcts=party_counts.div(party_counts.sum(1),axis=0)party_pctsparty_pcts.plot(kind='bar',stacked=True)# 3.長條圖和密度圖# 注意和前面的柱狀圖的區別,長條圖可以自動對給定的區間計數,繪製高度tips['tip_pct']=tips['tip']/tips['total_bill']tips['tip_pct'].hist(bins=50)# 4.密度曲線tips['tip_pct'].plot(kind='kde')# 將兩幅圖畫在一起comp1=np.random.normal(0,1,size=200)comp2=np.random.normal(10,2,size=200)values=Series(np.concatenate([comp1,comp2]))valuesvalues.hist(bins=100, alpha=0.3, color='k',normed=True)values.plot(kind='kde',style='k--')# 5.散布圖,散佈圖macro = pd.read_csv('macrodata.csv')data = macro[['cpi','m1','tbilrate','unemp']]trans_data = np.log(data).diff().dropna()trans_data[-5:]trans_data.tail()plt.scatter(trans_data['m1'],trans_data['unemp'])plt.title('change in log %s vs log %s' %('m1','unemp'))plt.show()# 5.2.散佈圖矩陣pd.scatter_matrix(trans_data,diagonal='kde', color='k', alpha=0.3)
python畫圖,最好的還是seaborn,繪製配色漂亮的統計圖形,其分組,分面,統計等,堪比ggplot啊。