matplotlib bar()实现多组数据并列柱状图通用简便创建方法


Posted in Python onFebruary 24, 2021

在使用柱状图时,经常遇到需要多组数据进行比较的情况。
绘制单个数据系列的柱形图比较简单,多组数据柱状图绘制的关键有三点:

  • 多次调用bar()函数即可在同一子图中绘制多组柱形图。
  • 为了防止柱子重叠,每个柱子在x轴上的位置需要依次递增,如果柱子紧挨,这个距离即柱子宽度。
  • 为了使刻度标签居中,需要调整x轴刻度标签的位置。

由上述可知,多组数据并列柱状图需要计算柱子x轴上的位置和x轴刻度标签。
因此,有两种实现方案:

  • x轴刻度标签位置固定,根据x轴刻度计算每个柱子的宽度
  • 每个柱子的宽度固定,计算x轴刻度标签位置,使之居中

下面使用第一种方法演示两组数据、三组数据、四组数据的并列柱状图。
使用方法一、方法二演示通用多组并列柱状图的创建方法。

两组数据、三组数据、四组数据的并列柱状图

matplotlib bar()实现多组数据并列柱状图通用简便创建方法

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(13, 4))
# 构造x轴刻度标签、数据
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]

# 两组数据
plt.subplot(131)
x = np.arange(len(labels)) # x轴刻度标签位置
width = 0.25 # 柱子的宽度
# 计算每个柱子在x轴上的位置,保证x轴刻度标签居中
# x - width/2,x + width/2即每组数据在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轴刻度标签位置不进行计算
plt.xticks(x, labels=labels)
plt.legend()
# 三组数据
plt.subplot(132)
x = np.arange(len(labels)) # x轴刻度标签位置
width = 0.25 # 柱子的宽度
# 计算每个柱子在x轴上的位置,保证x轴刻度标签居中
# x - width,x, x + width即每组数据在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轴刻度标签位置不进行计算
plt.xticks(x, labels=labels)
plt.legend()
# 四组数据
plt.subplot(133)
x = np.arange(len(labels)) # x轴刻度标签位置
width = 0.2 # 柱子的宽度
# 计算每个柱子在x轴上的位置,保证x轴刻度标签居中
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轴刻度标签位置不进行计算
plt.xticks(x, labels=labels)
plt.legend()

plt.show()

通用多组并列柱状图的简便创建方法

上面的示例比较简易,有一些问题没有考虑。为了便于重复使用,下面的通用方法可调整x轴标签刻度步长、每组柱子的总宽度、每组柱子之间的间隙、组与组之间的间隙。

matplotlib bar()实现多组数据并列柱状图通用简便创建方法

方法一

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轴坐标标签序列
  datas :数据集,二维列表,要求列表每个元素的长度必须与labels的长度一致
  tick_step :默认x轴刻度步长为1,通过tick_step可调整x轴刻度步长。
  group_gap : 柱子组与组之间的间隙,最好为正值,否则组与组之间重叠
  bar_gap :每组柱子之间的空隙,默认为0,每组柱子紧挨,正值每组柱子之间有间隙,负值每组柱子之间重叠
  '''
  # ticks为x轴刻度
  ticks = np.arange(len(labels)) * tick_step
  # group_num为数据的组数,即每组柱子的柱子个数
  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为每个柱子的实际宽度
  bar_width = bar_span - bar_gap
  # baseline_x为每组柱子第一个柱子的基准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轴刻度标签位置与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轴坐标标签序列
  datas :数据集,二维列表,要求列表每个元素的长度必须与labels的长度一致
  tick_step :默认x轴刻度步长为1,通过tick_step可调整x轴刻度步长。
  group_gap : 柱子组与组之间的间隙,最好为正值,否则组与组之间重叠
  bar_gap :每组柱子之间的空隙,默认为0,每组柱子紧挨,正值每组柱子之间有间隙,负值每组柱子之间重叠
  '''
  # x为每组柱子x轴的基准位置
  x = np.arange(len(labels)) * tick_step
  # group_num为数据的组数,即每组柱子的柱子个数
  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为每个柱子的实际宽度
  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轴刻度标签位置,即每组柱子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 相关文章推荐
python笔记(1) 关于我们应不应该继续学习python
Oct 24 Python
python正则表达式match和search用法实例
Mar 26 Python
详细解析Python中的变量的数据类型
May 13 Python
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
Dec 15 Python
python3.6 tkinter实现屏保小程序
Jul 30 Python
python开头的coding设置方法
Aug 08 Python
Python传递参数的多种方式(小结)
Sep 18 Python
python自动化测试无法启动谷歌浏览器问题
Oct 10 Python
python装饰器代替set get方法实例
Dec 19 Python
pytorch 计算ConvTranspose1d输出特征大小方式
Jun 23 Python
Pandas对每个分组应用apply函数的实现
Dec 13 Python
Python非单向递归函数如何返回全部结果
Dec 18 Python
pandas apply使用多列计算生成新的列实现示例
Feb 24 #Python
pandas map(),apply(),applymap()区别解析
Feb 24 #Python
Python的Tqdm模块实现进度条配置
Feb 24 #Python
详解pandas apply 并行处理的几种方法
Feb 24 #Python
python自动生成sql语句的脚本
Feb 24 #Python
Django与AJAX实现网页动态数据显示的示例代码
Feb 24 #Python
一文读懂python Scrapy爬虫框架
Feb 24 #Python
You might like
谈PHP生成静态页面分析 模板+缓存+写文件
2009/08/17 PHP
php smarty模版引擎中变量操作符及使用方法
2009/12/11 PHP
利用PHP扩展vld查看PHP opcode操作步骤
2013/03/04 PHP
CodeIgniter基本配置详细介绍
2013/11/12 PHP
php 购物车完整实现代码
2014/06/05 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
php模拟登陆的实现方法分析
2015/01/09 PHP
php获取访问者IP地址汇总
2015/04/24 PHP
PHP-FPM 的管理和配置详解
2019/02/17 PHP
js字符串的各种格式的转换 ToString,Format
2011/08/08 Javascript
JS实现可改变列宽的table实例
2013/07/02 Javascript
把字符串按照特定的字母顺序进行排序的js代码
2014/01/28 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
2014/04/17 Javascript
jquery 显示*天*时*分*秒实现时间计时器
2014/05/07 Javascript
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
Jquery 实现table样式的设定
2015/01/28 Javascript
深入理解Angular2 模板语法
2016/08/07 Javascript
在DWR中实现直接获取一个JAVA类的返回值的两种方法
2016/12/25 Javascript
bootstrap按钮插件(Button)使用方法解析
2017/01/13 Javascript
原生javascript上传图片带进度条【实例分享】
2017/04/06 Javascript
AngularJS改变元素显示状态
2017/04/20 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
2018/04/22 Javascript
vue登录页面cookie的使用及页面跳转代码
2019/07/10 Javascript
Webpack按需加载打包chunk命名的方法
2019/09/22 Javascript
Layer+Echarts构建弹出层折线图的方法
2019/09/25 Javascript
[04:26]DOTA2上海特锦赛小组赛第二日 TOP10精彩集锦
2016/02/27 DOTA
[01:00:59]VP VS VG Supermajor小组赛胜者组第二轮 BO3第二场 6.2
2018/06/03 DOTA
python正则表达式之对号入座篇
2018/07/24 Python
PyQt5实现简单数据标注工具
2019/03/18 Python
Python简易版图书管理系统
2019/08/12 Python
利用python对excel中一列的时间数据更改格式操作
2020/07/14 Python
python从Oracle读取数据生成图表
2020/10/14 Python
使用CSS3在触屏上为按钮实现激活效果
2013/09/27 HTML / CSS
学生会干部自我鉴定2014
2014/09/18 职场文书
2014保险公司内勤工作总结
2014/12/16 职场文书
OpenCV-Python实现轮廓的特征值
2021/06/09 Python