【matplotlib】可視化解決方案——柱狀圖標(biāo)注問題

柱狀圖標(biāo)注問題

前言

很多時候我們畫柱狀圖都是光禿禿的幾個柱體,缺少相應(yīng)的標(biāo)注會讓我們的可視化效果變差許多,例如下圖所示,所以為了更好的可視化效果,我們需要對柱狀圖進(jìn)行標(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)簽放置在柱體的端點(diǎn),顯示的值將是該端點(diǎn)的位置
center:標(biāo)簽位于柱體的中心,顯示的值將是該段的長度
參數(shù)5:padding:浮點(diǎn)型,指定標(biāo)簽到柱狀圖末端的距離
參數(shù)6: **kwargs:其余關(guān)鍵字參數(shù)都會傳遞給Axes.annotate

返回值:包含Text實(shí)例的列表


參數(shù)詳解:

1.fmt參數(shù)格式跟其他字符串顯示格式是一致的。
2.container參數(shù)不一定是bar函數(shù)的返回值,他可以是所有Patch類的子類實(shí)例


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')    #進(jìn)行標(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')    #進(jìn)行標(biāo)注
label(ax2)

plt.show()

畫圖結(jié)果如下:

在這里插入圖片描述

從上圖我們可以看出對于單一的柱狀圖,label_type參數(shù)沒有多大實(shí)質(zhì)影響,知識簡單的改變了標(biāo)注的位置。label_type參數(shù)真正的影響在于疊加柱狀圖時對兩種不同的柱狀圖進(jìn)行標(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方法對柱狀圖進(jìn)行標(biāo)注,默認(rèn)是在頂端進(jìn)行標(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ù)字代表兩個柱體加在一起的高度,即定點(diǎn)的高度。這樣我們就完成了兩個疊加柱狀圖的標(biāo)注。

?。。?!bar_label方法不光可以標(biāo)注柱狀圖還可以標(biāo)注直方圖等返回值具有patches屬性的圖


解決方案二

如果matplotlib庫版本較低,pyplot并不支持bar_label方法,那么只能使用自定義的添加函數(shù)進(jìn)行柱狀圖標(biāo)注了,使用annotate方法進(jìn)行標(biāo)注。具體程序如下:

    def autolabel(self, rects):
        """
        自動標(biāo)定柱狀圖柱體高度
        rects:要進(jìn)行標(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)注位置的高度使用的是柱體的高度而不是柱體頂點(diǎn)的值,那么對于疊加柱狀圖中的bottom參數(shù)則無法很好的響應(yīng),故而對疊加柱狀圖進(jìn)行標(biāo)注的效果很糟糕。


總結(jié)

如果能更新matplotlib庫,那么最好更新到3.4.1使用庫自帶方法進(jìn)行標(biāo)注,比自建函數(shù)要好上不少。但是舊版本可以通過添加參數(shù)或修改函數(shù)邏輯的方法增加其適用范圍,作為備選方法是可行的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容