【matplotlib】可视化解决方案——柱状图标注问题

柱状图标注问题

前言

很多时候我们画柱状图都是光秃秃的几个柱体,缺少相应的标注会让我们的可视化效果变差许多,例如下图所示,所以为了更好的可视化效果,我们需要对柱状图进行标注。
错误的无标注柱状图:

在这里插入图片描述

解决方案一

如果你的matplotlib库版本为3.4.1,那么pyplot库会自带一个方法bar_label,它的函数原型如下:

bar_label(container,labels = None,fmt = '%g',label_type = 'edge',padding = 0,**kwargs)

参数说明:

参数1:container:指定包含所有柱状图和错误条形图的容器,基本从bar函数或者barh函数返回
参数2:labels:指定应显示的标签文本列表。如果未给出,则标签文本将是使用fmt格式化的数据值
参数3:fmt:字符型,指定标签的格式字符串
参数4:label_type:指定标签的类型,{'edge','center'}
edge:标签放置在柱体的端点,显示的值将是该端点的位置
center:标签位于柱体的中心,显示的值将是该段的长度
参数5:padding:浮点型,指定标签到柱状图末端的距离
参数6: **kwargs:其余关键字参数都会传递给Axes.annotate

返回值:包含Text实例的列表


参数详解:

1.fmt参数格式跟其他字符串显示格式是一致的。
2.container参数不一定是bar函数的返回值,他可以是所有Patch类的子类实例


3.4.1版本标注程序如下:

#添加标签等函数
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)

#初始化数据
x = np.random.randint(0, 10, 10)

#画图1label_type='center'
Rectangle1 = ax1.bar(range(10), x, width=0.8, label='有标注,label_type=center')
ax1.bar_label(Rectangle1, label_type='center')    #进行标注
label(ax1)
ax1.set_title('bar画图', fontsize=25)

#画图2label_type='edge'
Rectangle2 = ax2.bar(range(10), x, width=0.8, label='有标注,label_type=edge')
ax2.bar_label(Rectangle2, label_type='edge')    #进行标注
label(ax2)

plt.show()

画图结果如下:

在这里插入图片描述

从上图我们可以看出对于单一的柱状图,label_type参数没有多大实质影响,知识简单的改变了标注的位置。label_type参数真正的影响在于叠加柱状图时对两种不同的柱状图进行标注。一个简单的示例如下:

#初始化数据
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')

#设置标签等
ax.set_ylabel('Y', fontsize=15)
ax.set_xlabel('X', fontsize=15)
ax.set_title('叠加柱状图', fontsize=25)
ax.legend() #打开图例
    
#使用bar_label方法对柱状图进行标注,默认是在顶端进行标注
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()

画图结果如下:

在这里插入图片描述

从上图可以看到柱体中心的数字代表该柱体的高度,柱体顶端的数字代表两个柱体加在一起的高度,即定点的高度。这样我们就完成了两个叠加柱状图的标注。

!!!!bar_label方法不光可以标注柱状图还可以标注直方图等返回值具有patches属性的图


解决方案二

如果matplotlib库版本较低,pyplot并不支持bar_label方法,那么只能使用自定义的添加函数进行柱状图标注了,使用annotate方法进行标注。具体程序如下:

    def autolabel(self, rects):
        """
        自动标定柱状图柱体高度
        rects:要进行标定的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()

单柱状图画图结果如下:

在这里插入图片描述

叠加柱状图画图结果如下:
在这里插入图片描述

由上两图可知,单一的柱状图标注使用该函数没有什么问题,但是叠加柱状图就出现了很大的问题,其原因在于height = rect.get_height()这句话,标注位置的高度使用的是柱体的高度而不是柱体顶点的值,那么对于叠加柱状图中的bottom参数则无法很好的响应,故而对叠加柱状图进行标注的效果很糟糕。


总结

如果能更新matplotlib库,那么最好更新到3.4.1使用库自带方法进行标注,比自建函数要好上不少。但是旧版本可以通过添加参数或修改函数逻辑的方法增加其适用范围,作为备选方法是可行的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容