在使用柱狀圖時(shí),經(jīng)常遇到需要多組數(shù)據(jù)進(jìn)行比較的情況。
繪制單個(gè)數(shù)據(jù)系列的柱形圖比較簡(jiǎn)單,多組數(shù)據(jù)柱狀圖繪制的關(guān)鍵有三點(diǎn):
- 多次調(diào)用bar()函數(shù)即可在同一子圖中繪制多組柱形圖。
- 為了防止柱子重疊,每個(gè)柱子在x軸上的位置需要依次遞增,如果柱子緊挨,這個(gè)距離即柱子寬度。
- 為了使刻度標(biāo)簽居中,需要調(diào)整x軸刻度標(biāo)簽的位置。
由上述可知,多組數(shù)據(jù)并列柱狀圖需要計(jì)算柱子x
軸上的位置和x
軸刻度標(biāo)簽。
因此,有兩種實(shí)現(xiàn)方案:
x
軸刻度標(biāo)簽位置固定,根據(jù)x
軸刻度計(jì)算每個(gè)柱子的寬度
- 每個(gè)柱子的寬度固定,計(jì)算
x
軸刻度標(biāo)簽位置,使之居中
下面使用第一種方法演示兩組數(shù)據(jù)、三組數(shù)據(jù)、四組數(shù)據(jù)的并列柱狀圖。
使用方法一、方法二演示通用多組并列柱狀圖的創(chuàng)建方法。
兩組數(shù)據(jù)、三組數(shù)據(jù)、四組數(shù)據(jù)的并列柱狀圖
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
plt.figure(figsize=(13, 4))
# 構(gòu)造x軸刻度標(biāo)簽、數(shù)據(jù)
labels = ['G1', 'G2', 'G3', 'G4', 'G5']
first = [20, 34, 30, 35, 27]
second = [25, 32, 34, 20, 25]
third = [21, 31, 37, 21, 28]
fourth = [26, 31, 35, 27, 21]
# 兩組數(shù)據(jù)
plt.subplot(131)
x = np.arange(len(labels)) # x軸刻度標(biāo)簽位置
width = 0.25 # 柱子的寬度
# 計(jì)算每個(gè)柱子在x軸上的位置,保證x軸刻度標(biāo)簽居中
# x - width/2,x + width/2即每組數(shù)據(jù)在x軸上的位置
plt.bar(x - width/2, first, width, label='1')
plt.bar(x + width/2, second, width, label='2')
plt.ylabel('Scores')
plt.title('2 datasets')
# x軸刻度標(biāo)簽位置不進(jìn)行計(jì)算
plt.xticks(x, labels=labels)
plt.legend()
# 三組數(shù)據(jù)
plt.subplot(132)
x = np.arange(len(labels)) # x軸刻度標(biāo)簽位置
width = 0.25 # 柱子的寬度
# 計(jì)算每個(gè)柱子在x軸上的位置,保證x軸刻度標(biāo)簽居中
# x - width,x, x + width即每組數(shù)據(jù)在x軸上的位置
plt.bar(x - width, first, width, label='1')
plt.bar(x, second, width, label='2')
plt.bar(x + width, third, width, label='3')
plt.ylabel('Scores')
plt.title('3 datasets')
# x軸刻度標(biāo)簽位置不進(jìn)行計(jì)算
plt.xticks(x, labels=labels)
plt.legend()
# 四組數(shù)據(jù)
plt.subplot(133)
x = np.arange(len(labels)) # x軸刻度標(biāo)簽位置
width = 0.2 # 柱子的寬度
# 計(jì)算每個(gè)柱子在x軸上的位置,保證x軸刻度標(biāo)簽居中
plt.bar(x - 1.5*width, first, width, label='1')
plt.bar(x - 0.5*width, second, width, label='2')
plt.bar(x + 0.5*width, third, width, label='3')
plt.bar(x + 1.5*width, fourth, width, label='4')
plt.ylabel('Scores')
plt.title('4 datasets')
# x軸刻度標(biāo)簽位置不進(jìn)行計(jì)算
plt.xticks(x, labels=labels)
plt.legend()
plt.show()
通用多組并列柱狀圖的簡(jiǎn)便創(chuàng)建方法
上面的示例比較簡(jiǎn)易,有一些問(wèn)題沒(méi)有考慮。為了便于重復(fù)使用,下面的通用方法可調(diào)整x軸標(biāo)簽刻度步長(zhǎng)、每組柱子的總寬度、每組柱子之間的間隙、組與組之間的間隙。
方法一
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
label = ['G1', 'G2', 'G3', 'G4', 'G5']
first = [20, 34, 30, 35, 27]
second = [25, 32, 34, 20, 25]
third = [21, 31, 37, 21, 28]
fourth = [26, 31, 35, 27, 21]
data = [first, second, third, fourth]
def create_multi_bars(labels, datas, tick_step=1, group_gap=0.2, bar_gap=0):
'''
labels : x軸坐標(biāo)標(biāo)簽序列
datas :數(shù)據(jù)集,二維列表,要求列表每個(gè)元素的長(zhǎng)度必須與labels的長(zhǎng)度一致
tick_step :默認(rèn)x軸刻度步長(zhǎng)為1,通過(guò)tick_step可調(diào)整x軸刻度步長(zhǎng)。
group_gap : 柱子組與組之間的間隙,最好為正值,否則組與組之間重疊
bar_gap :每組柱子之間的空隙,默認(rèn)為0,每組柱子緊挨,正值每組柱子之間有間隙,負(fù)值每組柱子之間重疊
'''
# ticks為x軸刻度
ticks = np.arange(len(labels)) * tick_step
# group_num為數(shù)據(jù)的組數(shù),即每組柱子的柱子個(gè)數(shù)
group_num = len(datas)
# group_width為每組柱子的總寬度,group_gap 為柱子組與組之間的間隙。
group_width = tick_step - group_gap
# bar_span為每組柱子之間在x軸上的距離,即柱子寬度和間隙的總和
bar_span = group_width / group_num
# bar_width為每個(gè)柱子的實(shí)際寬度
bar_width = bar_span - bar_gap
# baseline_x為每組柱子第一個(gè)柱子的基準(zhǔn)x軸位置,隨后的柱子依次遞增bar_span即可
baseline_x = ticks - (group_width - bar_span) / 2
for index, y in enumerate(datas):
plt.bar(baseline_x + index*bar_span, y, bar_width)
plt.ylabel('Scores')
plt.title('multi datasets')
# x軸刻度標(biāo)簽位置與x軸刻度一致
plt.xticks(ticks, labels)
plt.show()
create_multi_bars(label, data, bar_gap=0.1)
方法二
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
label = ['G1', 'G2', 'G3', 'G4', 'G5']
first = [20, 34, 30, 35, 27]
second = [25, 32, 34, 20, 25]
third = [21, 31, 37, 21, 28]
fourth = [26, 31, 35, 27, 21]
data = [first, second, third, fourth]
def create_multi_bars(labels, datas, tick_step=1, group_gap=0.2, bar_gap=0):
'''
labels : x軸坐標(biāo)標(biāo)簽序列
datas :數(shù)據(jù)集,二維列表,要求列表每個(gè)元素的長(zhǎng)度必須與labels的長(zhǎng)度一致
tick_step :默認(rèn)x軸刻度步長(zhǎng)為1,通過(guò)tick_step可調(diào)整x軸刻度步長(zhǎng)。
group_gap : 柱子組與組之間的間隙,最好為正值,否則組與組之間重疊
bar_gap :每組柱子之間的空隙,默認(rèn)為0,每組柱子緊挨,正值每組柱子之間有間隙,負(fù)值每組柱子之間重疊
'''
# x為每組柱子x軸的基準(zhǔn)位置
x = np.arange(len(labels)) * tick_step
# group_num為數(shù)據(jù)的組數(shù),即每組柱子的柱子個(gè)數(shù)
group_num = len(datas)
# group_width為每組柱子的總寬度,group_gap 為柱子組與組之間的間隙。
group_width = tick_step - group_gap
# bar_span為每組柱子之間在x軸上的距離,即柱子寬度和間隙的總和
bar_span = group_width / group_num
# bar_width為每個(gè)柱子的實(shí)際寬度
bar_width = bar_span - bar_gap
# 繪制柱子
for index, y in enumerate(datas):
plt.bar(x + index*bar_span, y, bar_width)
plt.ylabel('Scores')
plt.title('multi datasets')
# ticks為新x軸刻度標(biāo)簽位置,即每組柱子x軸上的中心位置
ticks = x + (group_width - bar_span) / 2
plt.xticks(ticks, labels)
plt.show()
create_multi_bars(label, data[:3], bar_gap=0.1)
您可能感興趣的文章:- Python matplotlib模塊及柱狀圖用法解析
- python調(diào)用matplotlib模塊繪制柱狀圖
- python使用matplotlib畫(huà)柱狀圖、散點(diǎn)圖
- python+matplotlib實(shí)現(xiàn)禮盒柱狀圖實(shí)例代碼
- python使用matplotlib繪制柱狀圖教程
- matplotlib bar()實(shí)現(xiàn)百分比堆積柱狀圖