柱狀圖標(biāo)注問題
前言
很多時候我們畫柱狀圖都是光禿禿的幾個柱體慈格,缺少相應(yīng)的標(biāo)注會讓我們的可視化效果變差許多,例如下圖所示遥金,所以為了更好的可視化效果浴捆,我們需要對柱狀圖進行標(biāo)注。
錯誤的無標(biāo)注柱狀圖:
解決方案一
如果你的matplotlib庫版本為3.4.1稿械,那么pyplot庫會自帶一個方法bar_label选泻,它的函數(shù)原型如下:
bar_label(container,labels = None,fmt = '%g'页眯,label_type = 'edge'梯捕,padding = 0,**kwargs)
參數(shù)說明:
參數(shù)1:container:指定包含所有柱狀圖和錯誤條形圖的容器窝撵,基本從bar函數(shù)或者barh函數(shù)返回
參數(shù)2:labels:指定應(yīng)顯示的標(biāo)簽文本列表傀顾。如果未給出,則標(biāo)簽文本將是使用fmt格式化的數(shù)據(jù)值
參數(shù)3:fmt:字符型碌奉,指定標(biāo)簽的格式字符串
參數(shù)4:label_type:指定標(biāo)簽的類型短曾,{'edge','center'}
edge:標(biāo)簽放置在柱體的端點道批,顯示的值將是該端點的位置
center:標(biāo)簽位于柱體的中心错英,顯示的值將是該段的長度
參數(shù)5:padding:浮點型,指定標(biāo)簽到柱狀圖末端的距離
參數(shù)6: **kwargs:其余關(guān)鍵字參數(shù)都會傳遞給Axes.annotate
返回值:包含Text實例的列表
參數(shù)詳解:
1.fmt參數(shù)格式跟其他字符串顯示格式是一致的隆豹。
2.container參數(shù)不一定是bar函數(shù)的返回值,他可以是所有Patch類的子類實例
3.4.1版本標(biāo)注程序如下:
#添加標(biāo)簽等函數(shù)
def label(ax):
ax.set_xlabel('X', fontsize=15)
ax.set_ylabel('Y', fontsize=15)
ax.legend(loc='best')
figure = plt.figure(figsize=(8, 6))
ax1 = figure.add_subplot(2, 1, 1)
ax2 = figure.add_subplot(2, 1, 2)
#初始化數(shù)據(jù)
x = np.random.randint(0, 10, 10)
#畫圖1label_type='center'
Rectangle1 = ax1.bar(range(10), x, width=0.8, label='有標(biāo)注,label_type=center')
ax1.bar_label(Rectangle1, label_type='center') #進行標(biāo)注
label(ax1)
ax1.set_title('bar畫圖', fontsize=25)
#畫圖2label_type='edge'
Rectangle2 = ax2.bar(range(10), x, width=0.8, label='有標(biāo)注,label_type=edge')
ax2.bar_label(Rectangle2, label_type='edge') #進行標(biāo)注
label(ax2)
plt.show()
畫圖結(jié)果如下:
從上圖我們可以看出對于單一的柱狀圖茅逮,label_type參數(shù)沒有多大實質(zhì)影響璃赡,知識簡單的改變了標(biāo)注的位置。label_type參數(shù)真正的影響在于疊加柱狀圖時對兩種不同的柱狀圖進行標(biāo)注献雅。一個簡單的示例如下:
#初始化數(shù)據(jù)
N = 5
Y1 = np.random.randint(0, 20, N)
Y2 = np.random.randint(0, 20, N)
fig, ax = plt.subplots()
#繪制疊加柱狀圖
p1 = ax.bar(range(N), Y1, width=0.6, label='Y1')
p2 = ax.bar(range(N), Y2, width=0.6, bottom=Y1, label='Y2')
#設(shè)置標(biāo)簽等
ax.set_ylabel('Y', fontsize=15)
ax.set_xlabel('X', fontsize=15)
ax.set_title('疊加柱狀圖', fontsize=25)
ax.legend() #打開圖例
#使用bar_label方法對柱狀圖進行標(biāo)注碉考,默認是在頂端進行標(biāo)注
ax.bar_label(p1, label_type='center', fontsize=13) #label_type='center'
ax.bar_label(p2, label_type='center', fontsize=13) #label_type='center'
ax.bar_label(p2, fontsize=13) #label_type='edge'
plt.show()
畫圖結(jié)果如下:
從上圖可以看到柱體中心的數(shù)字代表該柱體的高度,柱體頂端的數(shù)字代表兩個柱體加在一起的高度挺身,即定點的高度侯谁。這樣我們就完成了兩個疊加柱狀圖的標(biāo)注。
U录亍G郊!贱傀!bar_label方法不光可以標(biāo)注柱狀圖還可以標(biāo)注直方圖等返回值具有patches屬性的圖
解決方案二
如果matplotlib庫版本較低惨撇,pyplot并不支持bar_label方法,那么只能使用自定義的添加函數(shù)進行柱狀圖標(biāo)注了府寒,使用annotate方法進行標(biāo)注魁衙。具體程序如下:
def autolabel(self, rects):
"""
自動標(biāo)定柱狀圖柱體高度
rects:要進行標(biāo)定的Rectangle類列表
"""
for rect in rects:
height = rect.get_height()
self.fig1.axes.annotate(format(height, '.2f'),
xy=(rect.get_x() +
rect.get_width() / 2, height),
xytext=(0, 2), # 垂直偏移兩格
textcoords="offset points",
ha='center',
va='bottom')
self.fig1.draw()
單柱狀圖畫圖結(jié)果如下:
疊加柱狀圖畫圖結(jié)果如下:
由上兩圖可知,單一的柱狀圖標(biāo)注使用該函數(shù)沒有什么問題株搔,但是疊加柱狀圖就出現(xiàn)了很大的問題剖淀,其原因在于
height = rect.get_height()
這句話,標(biāo)注位置的高度使用的是柱體的高度而不是柱體頂點的值纤房,那么對于疊加柱狀圖中的bottom參數(shù)則無法很好的響應(yīng)纵隔,故而對疊加柱狀圖進行標(biāo)注的效果很糟糕。
總結(jié)
如果能更新matplotlib庫帆卓,那么最好更新到3.4.1使用庫自帶方法進行標(biāo)注巨朦,比自建函數(shù)要好上不少米丘。但是舊版本可以通過添加參數(shù)或修改函數(shù)邏輯的方法增加其適用范圍,作為備選方法是可行的糊啡。