在学习Matplotlib可视化过程中绘制一些相应的图形往往需要给图形添加数据标签这样才能通过图形更清楚的知道要表达的含义,下面通过一些简单的案例来讲解。
【案例一】
胡润财富榜:亿万资产超高净值家庭数
利用水平交错条形图对比2016年和2017年亿万资产超高净值家庭数(top5)
【需要运行出的效果如下】
【代码】
import matplotlib.pyplot as plt
import pandas as pd
# 解决乱码
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 导入数据
raw_data = {'城市': ['北京','上海','香港','深圳','广州'],
'2016': [15600,12700,11300,4270,3260],
'2017': [17400,14800,12000,5200,4020],}
# 创建数据框
df = pd.DataFrame(raw_data)
# 获取下标
pos = list(range(len(df['城市'])))
# 设置图形宽度
width = 0.3
# 绘图
plt.bar([p - width/2 for p in pos], df['2016'],width,color='#FFCCCC', label=df['城市'][0])
plt.bar([p + width/2 for p in pos], df['2017'], width, color='#6699CC', label=df['城市'][1])
# 设置x轴标签
plt.xticks(range(5),df['城市'])
# 设置y轴的范围
plt.ylim([2000,20000])
# 给图像加上图例
plt.legend(['2016','2017'],loc='upper right')
# 为每个条形图添加数值标签
for x,y in enumerate(df['2016']):
plt.text(x-0.13,y,'%s' %round(y),ha='center', va= 'bottom',fontsize=9)
for x,y in enumerate(df['2017']):
plt.text(x+0.09,y ,'%s' %round(y),ha='center', va= 'bottom',fontsize=9)
# 为x,y轴添加标签名
plt.xlabel('Top5 City')
plt.ylabel('Family Amount')
# 设置标题
plt.title('Millions Family Amount Top5 City Distribution')
# 显示
plt.show()
【解析】
1.如果输入的图形需要显示中文加入这两句代码就可以(解决Python matplotlib中文乱码问题)
# 解决乱码
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
2.将数据存入到数据框里面
# 导入数据
raw_data = {'城市': ['北京','上海','香港','深圳','广州'],
'2016': [15600,12700,11300,4270,3260],
'2017': [17400,14800,12000,5200,4020],}
# 创建数据框
df = pd.DataFrame(raw_data)
print(df)
然后打印下结果如下
城市 2016 2017
0 北京 15600 17400
1 上海 12700 14800
2 香港 11300 12000
3 深圳 4270 5200
4 广州 3260 4020
3.获取每座城市在数据框里面对应的下标
# 获取下标
pos = list(range(len(df['城市'])))
我们可以打印下pos
print(pos)
# 输出结果
[0,1,2,3,4]
4.绘图
# 设置图形宽度
width = 0.3
# 绘图
plt.bar([p - width/2 for p in pos], df['2016'],width,color='#FFCCCC', label=df['城市'][0])
plt.bar([p + width/2 for p in pos], df['2017'], width, color='#6699CC', label=df['城市'][1])
因为我们需要绘制2种条形图所以需要2个plt.bar(),好了你可能会问[p - width/2 for p in pos]和[p + width/2 for p in pos]是什么意思,那我们打印下看看
print([p - width/2 for p in pos])
print([p + width/2 for p in pos])
#输出结果
[-0.15, 0.85, 1.85, 2.85, 3.85]
[0.15, 1.15, 2.15, 3.15, 4.15]
可以看到打印出来的是一些数字,话句话说是坐标,为什么这样说呢,你首先要了解plt.bar()这个函数
plt.bar(x=x, # 柱体在 x 轴上的坐标位置
height=y, # 柱体的高度
align='center', # x 轴上的坐标与柱体对其的位置
color='bisque', # 柱体的填充颜色
tick_label=labels, # 每个柱体的标签名称
alpha=0.6, # 柱体填充颜色的透明度
width=0.8, # 柱体的宽度
bottom=0.2, # 柱体基线的 y 轴坐标
edgecolor='g', # 柱体的边框颜色
linewidth=1.5, # 柱体边框线的宽度
)
这样你应该懂了,相反后面的 df['2016']也就是条形图对应的y的值,这样下来我们就确定了(x,y)坐标了,然后就是那个width就是条形图的图形宽度。
5.设置x轴标签
# 设置x轴标签
plt.xticks(range(5),df['城市'])
看懂这段代码你首先得知道plt.xticks()函数,这个函数就是显示条形图中x对应的文字
plt.xticks([-1,0,1],['-1','0','1'])
第一个:对应X轴上的值,第二个:显示的文字
range(5)的结果为[0,1,2,3,4]
df['城市']对应的结果为:北京、上海、香港、深圳、广州
然后结合下就是(0,北京)、(1,上海)、(2,香港)、(3,深圳)、(4,广州)
6. 设置y轴的范围(这个没啥好解释的)
# 设置y轴的范围
plt.ylim([2000,20000])
7. 给图像加上图例
# 给图像加上图例
plt.legend(['2016','2017'],loc='upper right')
这段代码就是显示条形图中2种颜色代表的含义在右上角那个图标显示如果你写成plt.legend()也可以
8.为每个条形图添加数值标签
# 为每个条形图添加数值标签
for x,y in enumerate(df['2016']):
plt.text(x-0.13,y,'%s' %round(y),ha='center', va= 'bottom',fontsize=9)
for x,y in enumerate(df['2017']):
plt.text(x+0.09,y ,'%s' %round(y),ha='center', va= 'bottom',fontsize=9)
理解这段代码你需要了解enumerate()函数和plt.text()函数
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
以下是 enumerate() 方法的语法:
enumerate(sequence, [start=0])
>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
... print i, element
...
0 one
1 two
2 three
plt.text(x,
y,
string,
fontsize=15,
verticalalignment="top",
horizontalalignment="right"
)
x,y:表示坐标值上的值
string:表示说明文字
fontsize:表示字体大小
verticalalignment:垂直对齐方式 ,参数:[ ‘center’ | ‘top’ | ‘bottom’ | ‘baseline’ ]
horizontalalignment:水平对齐方式 ,参数:[ ‘center’ | ‘right’ | ‘left’ ]
fontsize,style,ha,va参数分别是字号,字体,垂直对齐方式,水平对齐方式。
看懂了enumerate()函数你大概知道了x和y的意思把,就是坐标轴上x和y,通过for循环遍历df['2016']这个数据集
接下来你可能很好奇plt.text()里面的x-0.13和x+0.09是什么意思,这里主要的调整下x坐标对应的y的值在条形图上的对齐位置,如果你们不知道你可以试一试直接写x看看效果是什么。
9.显示图形
# 设置标题
plt.title('Millions Family Amount Top5 City Distribution')
# 显示
plt.show()