图形标注
有时候我们画好了一幅图,比如柱状图,但是如何在每个柱子上面显示其具体的数据呢?简单的plot.bar()是无法解决这个问题的。今天就遇到了这个问题,发现annotate是一个提供标注的工具,可以解决此类问题。annotate的功能很强大,在图中加文本框,加箭头都可以。
实例
最近在做Titanic 数据分析,分类型变量的单变量分析一般需要画柱状图,在图上加上具体的数值再好不过了。
#定义柱状图显示函数:
def abs_rel_f(feature):
#生成频率的dataframe格式:
abs_frequency=feature.value_counts()
relative_frequency=feature.value_counts(normalize=True).round(3)*100
abs_rel_f=pd.DataFrame({'Absolute Frequency':abs_frequency,'Relative Frequency(%)':relative_frequency})
display(abs_rel_f)
#绘制柱状图
#绝对频率柱状图:
global ax,ax1 #声明全局变量,这样上面的绝对和相对频率注释函数才可以使用ax和ax1
ax=abs_frequency.plot.bar(figsize=(18,7))
abs_bar_labels() # Displays bar labels in abs scale.
plt.show()
#相对频率柱状图:
ax1=relative_frequency.plot.bar(figsize=(18,7))
pct_bar_labels()
plt.show()
注意:
1 统计变量的频率,使用pandas的value_counts()函数
2 统计相对频率(即百分比),只需要value_counts( normalize=True) 计算百分比,元整的话要加 .round(n) ,小数点后保留n位
3 global 是声明全局变量,即ax和ax1不仅仅在函数内有效,所以函数外面的也可以调用ax、ax1
4 两个ax相当于两个画布,要全部显示的话,一个 plt.show( )不够,需要每一个ax下都加 plt.show( )
5 便是abs_bar_labels 和 pct_bar_labels,这两个便是两个柱状图的标注函数,如下:
设置标注函数
# 定义相对频率柱状图的注释
def abs_bar_labels():
font_size = 15
plt.ylabel('Absolute Frequency', fontsize = font_size)
plt.xticks(rotation =0, fontsize = font_size)
plt.yticks([])
# Set individual bar lebels in absolute number
for x in ax.patches:
ax.annotate(x.get_height(),
(x.get_x() + x.get_width()/2., x.get_height()), ha = 'center', va = 'center',xytext = (0,7),
textcoords = 'offset points', fontsize = font_size, color = 'black')
# 定义相对频率柱状图的注释
def pct_bar_labels():
font_size = 15
plt.ylabel('Relative Frequency (%)', fontsize = font_size)
plt.xticks(rotation = 0, fontsize = font_size)
plt.yticks([])
# Set individual bar lebels in proportional scale
for x in ax1.patches:
ax1.annotate(str(x.get_height()) + '%',
(x.get_x() + x.get_width()/2., x.get_height()), ha = 'center', va = 'center', xytext = (0, 7),
textcoords = 'offset points', fontsize = font_size, color = 'black')
ax.annotate((x.get_height(),
(x.get_x() + x.get_width()/2., x.get_height()), ha = 'center', va = 'center',xytext = (0,7),
textcoords = 'offset points', fontsize = font_size, color = 'black')参数详解:ax.annotata( (y, (x,y) ),ha, va, xytext, textcoords, fontsize, color )
y : 要标注的值或字符串。x.get_x() 即横坐标对应的纵坐标的值
(x, y): 被标注的点或区域。(x.get_x() + x.get_width()/2., x.get_height())即(横坐标值+柱的宽度,柱的高度)
ha va=' center' 点在注释的中心。ha 水平(right left center)放置、 va 垂直放置方式 ( top center baseline bottom )
xytext: 标注文本所处的坐标。( 0,7) 是相对坐标,x坐标移动为0, 纵坐标向上移动7
textcoords = 'offset points' 以上述被标注的点(x,y)为起点,是计算xytext 绝对坐标的起点
因为相对频率柱形图中,标注的数字要加' %',所以标注函数里y 那项变为字符串形式: str(x.get_height()) + '%'
结果如下:
参考:https://www.kaggle.com/eraaz1/a-comprehensive-guide-to-titanic-machine-learning/notebook