柱状图和直方图是两种非常类似的统计图,区别在于:
-
直方图展示数据的分布,柱状图比较数据的大小。
-
直方图X轴为定量数据,柱状图X轴为分类数据。因此,直方图上的每个条形都是不可移动的,X轴上的区间是连续的、固定的。而柱状图上的每个条形是可以随意排序的,有的情况下需要按照分类数据的名称排列,有的则需要按照数值的大小排列。
-
直方图柱子无间隔,柱状图条形有间隔
-
直方图条形宽度可不一,柱状图条形宽度须一致。柱状图条形的宽度因为没有数值含义,所以宽度必须一致。但是在直方图中,条形的宽度代表了区间的长度,根据区间的不同,条形的宽度可以不同,但理论上应为单位长度的倍数。
本篇博客将介绍matplotlib中柱状图和直方图的作图方法。
In [1]:
from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParams['font.sans-serif'] = ['SimHei'] # 中文字体支持
1 bar()与barh()
matplotlib中提供了bar()和barh()两种方法画柱状图,bar()用来画垂直柱状图,barh()画水平柱状图,两者参数大同小异,如下所示:
2 垂直柱状图与水平柱状图
In [2]:
value= np.arange(6) ** 2 category = range(len(value)) fig = plt.figure(figsize=(8, 4)) # 垂直柱状图 ax1 = fig.add_subplot(121) ax1.set_title('图1 垂直柱状图') ax1.bar(x=category, height=value) # 垂直柱状图 ax2 = fig.add_subplot(122) ax2.set_title('图2 水平柱状图') ax2.barh(y=category, width=value) # 注意这里参数名和值的传递与bar()不同 plt.show()
3 颜色、透明度与边框
In [3]:
value= np.arange(6) ** 2 category = range(len(value)) fig = plt.figure(figsize=(8, 4)) # 垂直柱状图 ax1 = fig.add_subplot(121) ax1.set_title('图1 垂直柱状图') ax1.bar(x=category, height=value, alpha=0.5, # 透明度 width=0.5, # 每个条形的宽度 color='yellow', # 填充前景色 edgecolor='red', # 边框颜色 linewidth=3 # 边框宽度 ) # 垂直柱状图 ax2 = fig.add_subplot(122) ax2.set_title('图2 水平柱状图') ax2.barh(y=category, width=value, alpha=1, # 透明度 height=0.8, # 每个条形的宽度 color=['green', 'red', 'yellow', 'blue', 'grey', 'magenta'], # 填充前景色 linewidth=3 # 不显示边框 ) plt.show()
4 刻度标签
In [4]:
value= np.arange(6) ** 2 category = range(len(value)) fig = plt.figure(figsize=(8, 4)) # 垂直柱状图 ax1 = fig.add_subplot(121) ax1.set_title('图1 垂直柱状图') ax1.bar(x=category, height=value, tick_label='类别' ) # 垂直柱状图 ax2 = fig.add_subplot(122) ax2.set_title('图2 水平柱状图') ax2.barh(y=category, width=value, tick_label=['类1', '类2', '类3', '类4', '类5', '类6'] ) plt.show()
5 添加误差线
In [5]:
means = (20, 35, 30, 35, 27) # 各组平均分 std = (2, 3, 4, 1, 2) # 组各标准差 label = ('第一组', '第二组', '第三种', '第四组', '第五组') bar_width = 0.4 bar_x = np.arange(len(label)) fig = plt.figure(figsize=(8, 4)) ax1 = fig.add_subplot(121) bar1 = ax1.bar(x=bar_x, height=means, width=bar_width, color='green', yerr=std, # 添加误差线 ecolor='red', # 误差线颜色 capsize=5, # 两端线段长短 tick_label=label ) ax2 = fig.add_subplot(122) bar2 = ax2.barh(y=bar_x, width=means, height=bar_width, color='green', xerr=std, # 添加误差线 ecolor='red', # 误差线颜色 capsize=5, # 两端线段长短 tick_label=label ) plt.show()
6 添加数据标注
In [6]:
means = (20, 35, 30, 35, 27) # 各组平均分 std = (2, 3, 4, 1, 2) # 组各标准差 label = ('第一组', '第二组', '第三种', '第四组', '第五组') bar_width = 0.5 bar_x = np.arange(len(label)) fig = plt.figure(figsize=(10, 4),tight_layout=True) ax1 = fig.add_subplot(121) bar1 = ax1.bar(x=bar_x, height=means, width=bar_width, color='green', tick_label=label ) for b in bar1: height = b.get_height() ax1.annotate('{}'.format(height), xy=(b.get_x() + b.get_width() / 2, height), xytext=(0, 3), # 3 points vertical offset textcoords="offset points",color='red', ha='center', va='bottom') ax2 = fig.add_subplot(122) bar2 = ax2.barh(y=bar_x, width=means, height=bar_width, color='green', tick_label=label ) for b in bar2: width = b.get_width() ax2.annotate('{}'.format(width), xy=(width, b.get_y() + b.get_height() /