作者是跟着http://t.csdnimg.cn/4fVW0学习的,matplotlib系列文章是http://t.csdnimg.cn/4fVW0的自己学习过程中整理的详细说明版本,对小白更友好哦!
四、条形图
1. 一个数据样本的条形图
- 条形图:常用于比较不同类别的数量或值,以及进行简单的数据分析。
- 直方图:常用于分析数据的集中趋势、离散程度以及异常值的存在。
区别 | 频数分布直方图 | 条形图 |
---|---|---|
横轴上的数据 | 连续的,是一个范围 | 孤立的,代表一个类别 |
长条形之间 | 没有空隙 | 有空隙 |
频数的表示 | 一般用面积表示;当宽度相同时,用长度表示 | 长条形的高度 |
代码详解:
n = 12
这行代码定义了条形图中的条形数量,这里设置为12。
X = np.arange(n)
这行代码使用NumPy的arange
函数创建一个数组,包含从0到n-1
的整数,这个数组将用于条形图的x轴坐标。
Y1 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
这行代码计算第一个条形图的高度。每个高度是通过一个随机数乘以(1-X/float(n))
得到的,这样可以确保条形图从左到右逐渐减小。np.random.uniform(0.5,1.0,n)
生成一个包含n个随机数的数组,每个数在0.5到1.0之间。
Y2 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
这行代码与上面类似,计算第二个条形图的高度。
bar(X, -Y2, facecolor='#ff9999', edgecolor='white')
这行代码在同一个x轴坐标上绘制第二个条形图,但是高度为负值,这样两个条形图就会堆叠在一起。
for x,y in zip(X,Y1):
这个循环遍历X
和Y1
数组的元素,将Y1
的值作为文本绘制在每个条形上方。
text(x, y+0.05, '%.2f' % y, ha='center', va= 'bottom')代码详解:
x, y+0.05
:这两个参数指定了文本在图表中的位置。x
是条形的x轴坐标,y+0.05
表示在条形的顶部加上0.05的偏移量,这样文本就会出现在条形的上方。偏移量确保文本不会与条形图重叠。
'%0.2f' % y
:这是一个格式化字符串,用于将y
的值格式化为带有两位小数的浮点数。%0.2f
中的%
是一个占位符,0.2f
指定了浮点数的格式:至少一位整数,最多两位小数,小数点后不足两位的部分用0填充。
ha='center'
:这个参数指定了文本的水平对齐方式。ha
是horizontalalignment
的缩写,'center'
表示文本应该水平居中对齐,即文本的中心位于指定的x坐标上。
va='bottom'
:这个参数指定了文本的垂直对齐方式。va
是verticalalignment
的缩写,'bottom'
表示文本的底部与指定的y坐标对齐,即文本的底部位于指定的y坐标上。
from pylab import *
n = 12
X = np.arange(n)
Y1 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
Y2 = (1-X/float(n)) * np.random.uniform(0.5,1.0,n)
bar(X, +Y1, facecolor='#9999ff', edgecolor='white')
bar(X, -Y2, facecolor='#ff9999', edgecolor='white')
#xticks(X)
for x,y in zip(X,Y1):
text(x, y+0.05, '%.2f' % y, ha='center', va= 'bottom')
for x, y in zip(X, -Y2):
text(x, y-0.15, '%.2f'% y, ha='center', va='bottom')
ylim(-1.25,+1.25)
show()
2. 多个数据样本的条形图
# 设置中文字体和负号正常显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
label_list = ['2014', '2015', '2016', '2017'] # 横坐标刻度显示值
num_list1 = [20, 30, 15, 35] # 纵坐标值1
num_list2 = [15, 30, 40, 20] # 纵坐标值2
x = range(len(num_list1))
# 绘制条形图
rects1 = plt.bar(x, height=num_list1, width=0.4, alpha=0.5, color='gold', label='部门一')
rects2 = plt.bar([i+0.4 for i in x], height=num_list2, width=0.4, color='lightcyan', label='部门二')
# 设置y轴属性
plt.ylim(0, 50)
plt.ylabel('数量')
# 设置x轴属性
plt.xticks([index+0.2 for index in x], label_list)
plt.xlabel("年份")
plt.title('某某公司')
plt.legend()
# 显示文本
for rect in rects1:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height + 1, str(height), ha='center', va='bottom')
for rect in rects2:
height = rect.get_height()
plt.text(rect.get_x() + rect.get_width() / 2, height + 1, str(height), ha='center', va='bottom')
plt.show()
3. 水平条形图
代码详解:
price = [39.5, 39.9, 45.4, 38.9, 33.34]
:这行代码定义了一个列表price
,包含了5个数值,分别代表了不同平台的图书价格。
plt.barh(range(5), price, height=0.7, color='steelblue', alpha=0.5)
:这行代码使用plt.barh()
函数绘制了一个水平条形图。range(5)
生成了一个从0到4的整数序列,用于指定每个条形的位置。price
列表中的值被用来填充条形的高度。
plt.yticks(range(5), ['亚马逊', '当当网', '中国图书网', '京东', '天猫'])
:这行代码设置了y轴的刻度标签,与条形的位置对应,这里使用了中文标签。
for x, y in enumerate(price):
:这行代码开始了一个循环,enumerate(price)
会生成一个包含索引和价格的元组序列,然后for
循环会遍历这个序列。
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
price = [39.5, 39.9, 45.4, 38.9, 33.34]
# 绘制水平条形图
plt.barh(range(5), price, height=0.7, color='steelblue', alpha=0.5)
plt.yticks(range(5), ['亚马逊', '当当网', '中国图书网', '京东', '天猫'])
plt.xlim(30, 47)
plt.xlabel('价格')
plt.title('不同平台图书价格')
for x, y in enumerate(price):
plt.text(y+0.2, x-0.1, '%s'%y)
plt.show()
4. 绘制不同数据样本进行对比的水平条形图
代码详解:
y = range(1, len(num_list1)+1)
:这行代码使用range()
函数创建了一个整数序列,从1开始,到num_list1
的长度加1结束。这个序列将用于确定条形图的y轴位置。
y = [index*1.5 for index in y]
:这行代码通过列表推导式创建了一个新的列表y
,每个元素都是原列表y
中对应元素的1.5倍。这会将条形图的y轴位置放大,以便于在同一个图表中绘制两个条形图。
plt.barh(y, num_list1, height=0.4, color='gold', alpha=0.5)
:这行代码使用plt.barh()
函数绘制了第一个条形图。y
列表中的值被用来确定条形的位置,num_list1
列表中的值被用来填充条形的高度。
plt.barh([index-0.4 for index in y], num_list2, height=0.4, color='paleturquoise', alpha=0.5)
:这行代码使用plt.barh()
函数绘制了第二个条形图。这里使用了列表推导式来创建一个新的y
列表,每个元素是原列表y
中对应元素的减去0.4,以便于在第一个条形图的下方绘制第二个条形图。
plt.text(x+0.8, y1-0.1, str(x), ha='center', va='bottom')
:这行代码在每个条形旁边添加了数量标签。x+0.8
确保了标签不会被条形覆盖,而y1-0.1
确保了标签不会被y轴的刻度覆盖。
for x, y2 in zip(num_list2, y):
:这行代码开始了一个新的循环,用于添加第二个条形图的数量标签。
plt.text(x+0.8, y2-0.5, str(x), ha='center', va='bottom')
:这行代码在每个条形旁边添加了第二个数量标签。x+0.8
确保了标签不会被条形覆盖,而y2-0.5
确保了标签不会被y轴的刻度覆盖。
label_list = ['2014', '2015', '2016', '2017']
num_list1 = [20, 30, 15, 35]
num_list2 = [15, 33, 40, 20]
y = range(1, len(num_list1)+1)
y = [index*1.5 for index in y]
plt.barh(y, num_list1, height=0.4, color='gold', alpha=0.5)
plt.barh([index-0.4 for index in y], num_list2, height=0.4, color='paleturquoise', alpha=0.5)
plt.yticks([index-0.2 for index in y], label_list)
plt.ylabel('年份')
plt.xlim(0, 45)
plt.xlabel('数量')
for x, y1 in zip(num_list1, y):
plt.text(x+0.8, y1-0.1, str(x), ha='center', va='bottom')
for x, y2 in zip(num_list2, y):
plt.text(x+0.8, y2-0.5, str(x), ha='center', va='bottom')
plt.show()