本節提要:matplotlib中的柱狀圖系列,bar、barh繪圖函數的常見參數與應用實例。
一、簡談柱狀圖
import matplotlib.pyplot as pltimport numpy as npimport matplotlib.ticker as mtickerplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedef sample_data(): x=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]) y=np.array([11,14,18,2,16,4,15,3,19,17,4,11,1,18,14,3,13,19,2,3]) return x,yx,y=sample_data()fig=plt.figure(figsize=(4,2),dpi=500)ax1=fig.add_axes([0,0,1,0.4])ax2=fig.add_axes([0,0.5,1,0.4])ax1.bar(x,y,color='tab:green')ax2.bar(x,y,color='tab:blue')ax1.set_ylim(0,20)ax1.tick_params(axis='both',which='both',direction='in')ax1.xaxis.set_major_locator(mticker.MultipleLocator(5))ax1.yaxis.set_minor_locator(mticker.MultipleLocator(2))ax2.set_ylim(0,20)ax2.tick_params(axis='both',which='both',direction='in')ax2.xaxis.set_major_locator(mticker.MultipleLocator(5))ax2.yaxis.set_minor_locator(mticker.MultipleLocator(2))plt.show()ax1.bar(x,y,width=0.75)ax2.bar(x,y,width=0.25)ax1.bar(x,y,bottom=2)ax2.bar(x,y,bottom=10)
ax1.bar(x,y,edgecolor='r')ax2.bar(x,y,edgecolor='k')ax1.bar(x,y,linewidth=5,edgecolor='k')ax2.bar(x,y,linewidth=2.55,edgecolor='k')xerr,yerr
誤差線
ecolor
誤差線顏色
capsize
誤差線帽長度ax1.bar(x,y,yerr=True,ecolor='r',capsize=1)ax2.bar(x,y,xerr=True,ecolor='tab:green',capsize=3)ax1.bar(x,y,hatch='xxx')ax2.bar(x,y,hatch='*')ax1.bar(x,y,color='tab:green',alpha=0.5)ax2.bar(x,y,color='tab:green',alpha=0.1)本節主要簡單介紹柱狀圖的一些實用繪製方法:
A、如何使柱體在區分正負值(特別是距平),或者突破某一限制值柱體的顏色能夠不一致
只需要一個np.where( )命令即可完成,這個命令在前面已經介紹過了,這裡也可以用,看不懂就跑代碼編代碼。
import matplotlib.pyplot as pltimport numpy as npimport matplotlib.ticker as mtickerplt.rcParams['font.sans-serif']=['SimHei']plt.rcParams['axes.unicode_minus']=Falsedef sample_data(): x=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21, 22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50]) x2=np.array([1,2,3,4,5]) y1=np.array([11,14,18,2,16,-4,-15,3,19,17,-4,11,20,18,14,3,13,19,2,3,16,15,12, 10,4,-2,-4,-11,-18,-17,-3,5,9,15,17,8,9,16,14,11,-8,5,17,6,-9,-5,11, -7,-2,10]) y2=np.array([14,4,6,14,18,15,19,21,-9,-6,-4,-2,-1,-3,-5,-6,-8,1,11,9,15,13,17, 19,10,4,6,9,2,12,11,8,-7,-9,5,5,4,15,12,13,-9,2,1,4,11,15,17,8,11,16]) y3=np.array([1120,1230,1190,1340,1590,1180,1390,1520,1690,1370,1210,1550,1555,1320,1221,1421, 1321,1532,1432,1222,1243,1543,1121,1672,1389,1567,1678,1224,1521,1790,1810,1146, 1356,1455,1789,1567,1234,1120,1675,1879,1800,1567,1235,1786,1346,1345,1789,1435,1567,1333]) y4=np.array([24,27,29,35,33,21]) y5=np.array([14,24,27,19,30]) return x,x2,y1,y2,y3,y4,y5x,x2,y1,y2,y3,y4,y5=sample_data()fig=plt.figure(figsize=(5,4),dpi=600)ax1=fig.add_axes([0,0,1,0.4])ax2=fig.add_axes([0,0.5,1,0.4])ax1.bar(x,y1,color=np.where(y1>0,'tomato','tab:blue'))ax2.bar(x,y2,color='k')ax1.set_ylim(-20,25)ax1.tick_params(axis='both',which='both',direction='in')ax1.yaxis.set_minor_locator(mticker.MultipleLocator(5))ax1.set_xlabel('時刻')ax1.set_ylabel('數值')ax2.set_ylim(-20,25)ax2.tick_params(axis='both',which='both',direction='in')ax2.yaxis.set_minor_locator(mticker.MultipleLocator(1))ax2.set_xlabel('時刻')ax2.set_ylabel('數值')plt.title('柱狀圖')plt.savefig('a',bbox_inches='tight')plt.show()fig=plt.figure(figsize=(5,2),dpi=500)ax=fig.add_axes([0,0,1,1])ax.bar(x,y3,color=np.where(y3>1600,'tomato','tab:blue'))ax.axhline(y=1600,c='k',ls=':',lw=1)ax.set_ylim(1000,2000)ax.tick_params(axis='both',which='both',direction='in')ax.yaxis.set_minor_locator(mticker.MultipleLocator(100))ax.text(45,1650,'某個限定值')ax.set_title('限值變色')plt.savefig('a',bbox_inches='tight')plt.show()B、如何並列多個數據(即類似第一節圖二)
其實就是把每個柱體的橫坐標挪動一下,我的數據比較小,所以是手動挪動,如果超過三種,最好用公式來挪動。
fig=plt.figure(figsize=(3,1.5),dpi=600)#添加畫布等ax=fig.add_axes([0,0,1,1])bar1=ax.bar(x2-0.22,y4,width=0.45)bar2=ax.bar(x2+0.23,y5,width=0.45)ax.set_title('並列柱狀圖',fontsize=10)ax.set(xlim=(0,7),ylim=(0,40))ax.tick_params(axis='both',which='both',direction='in')ax.yaxis.set_minor_locator(mticker.MultipleLocator(5))C、如何在柱體頭部標值
可以手動讀取,也可以參考官網的方法,獲得當前柱體高度,然後標值
fig=plt.figure(figsize=(3,1.5),dpi=600)ax=fig.add_axes([0,0,1,1])bar1=ax.bar(x2-0.22,y4,width=0.45)bar2=ax.bar(x2+0.23,y5,width=0.45)ax.set_title('並列柱狀圖',fontsize=10)ax.set(xlim=(0,7),ylim=(0,40))ax.tick_params(axis='both',which='both',direction='in')ax.yaxis.set_minor_locator(mticker.MultipleLocator(5))def autolabel(rects): for rect in rects: height = rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), textcoords="offset points", ha='center', va='bottom')autolabel(bar1)autolabel(bar2)D、黑白刊物投稿
現在很多其實已經是彩色刊物了,但是仍然留在此處參考。
一般繪製圖片時,選取在色盤上成對角關係的顏色,列印成黑白的照片後仍然可以清晰的分辨每種柱體;或者使用前面提到的關鍵字參數hatch來改變內部填充樣式分辨柱體。
bar1=ax.bar(x2-0.22,y4,edgecolor='k',facecolor='none',hatch='*',width=0.45)bar2=ax.bar(x2+0.23,y5,edgecolor='k',facecolor='none',hatch='/',width=0.45)E、堆積柱狀圖
這個圖的繪製要用到bottom參數,將第二個bar的下界設定為第一個bar高度值
fig=plt.figure(figsize=(3,1.5),dpi=600)ax=fig.add_axes([0,0,1,1])bar1=ax.bar(x2,y4)bar2=ax.bar(x2,y5,bottom=y4)ax.set_title('堆積柱狀圖',fontsize=10)ax.set(xlim=(0,6.5),ylim=(0,80))ax.tick_params(axis='both',which='both',direction='in')ax.yaxis.set_minor_locator(mticker.MultipleLocator(5))F、給柱狀圖添加圖例
使用legend( )命令來給柱狀圖添加圖例
fig=plt.figure(figsize=(4,2),dpi=600)ax=fig.add_axes([0,0,1,1])width=0.45bar1=ax.bar(x2-width/2,y4,width)bar2=ax.bar(x2+width/2,y5,width)ax.legend([bar1,bar2],['藍色柱形','橙色柱形'])參考資料:
1961至2010 年利川市極端氣溫變化分析 , 張成平, 資源與環境科學
人類活動排放的CO及氣溶膠對20世紀70年代末中國東部夏季降水年代際轉折的影響 ,王歡 李棟梁 ,氣象學報
集合柱狀圖與標記數值:https://matplotlib.org/gallery/lines_bars_and_markers/barchart.html#sphx-glr-gallery-lines-bars-and-markers-barchart-py