首发于R语言

R语言:使用barplot()绘制柱状图(条形图)

柱状图(条形图)是一类非常重要的统计图表,在数据分析中的使用频率很高,今天我们就来一起看看在R语言中如何绘制柱状图,本文基本上涵盖了我在数据分析项目中绘制柱状图的全部需求,希望能够帮助大家一次性“搞定”柱状图。

一、绘图参数概览

R语言内部自带的绘制条形图的函数barplot()已经比较强大,可以满足我们大部分需求,常用的参数如下:

barplot(height,              # 柱子的高度
        names.arg = NULL,    # 柱子的名称
        col = NULL,          # 柱子的填充颜色
        border = par("fg"),  # 柱子的轮廓颜色
        main = NULL,         # 柱状图主标题
        xlab = NULL,         # X轴标签
        ylab = NULL,         # Y轴标签
        xlim = NULL,         # X轴取值范围
        ylim = NULL,         # Y轴取值范围
        horiz = FALSE,       # 柱子是否为水平
        legend.text = NULL,  # 图例文本
        beside = FALSE,      # 柱子是否为平行放置
       )

二、绘图参数详解

1. height:柱子的高度

绘图数据height是必须要传入的参数,数据类型可以是数值型向量或者矩阵。如果传入一个数值型向量,那么向量中的每个数字即为每个柱子的高度,适用于绘制单个变量的柱状图;如果传入一个矩阵,那么矩阵的每一列都对应一个柱子,柱子的高度为每一列的数字之和,每个柱子内部根据每一行数字的不同进行了划分,适用于两个变量交叉的柱状图。下面我们看一个实例:

# 传入数值型向量
vector = c(6, 4, 8) # 绘图数据(数值型向量)
barplot(height = vector)  # 绘制条形图
# 传入矩阵
matrix = matrix(1:4, ncol = 2, nrow = 2)  # 绘图数据(矩阵)
barplot(height = matrix)  # 绘制条形图

2. names.arg:柱子的名称

从上面的实例中可以看出,如果在height参数中只传入一个数值型向量或者矩阵的话,绘制出来的柱状图是没有柱子名称的,因此需要手动更改names.arg参数来增加柱子名称。names.arg是一个数值型或者字符型向量,长度与柱子的数量(height的长度或列数)相同。(如果想在图中正常显示中文的话,需要设置参数family = "Kai"或者其他字体 ),下面我们来看一个实例:

barplot(height = c(6, 4, 8),  # 绘图数据(数值型向量)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai'  # 中文字体
       )

3. colborder:填充颜色、轮廓颜色

col参数代表着柱子的填充颜色,border参数代表轮廓颜色。如果height传入的是一维数值型向量,那么colborder只需要传入一个代表颜色的字符串(例如:darkblue、yellow、green等),或者一个十六进制的RGB数值(例如:#98F5FF);如果height传入的是二维矩阵,那么colborder则需要传入一个颜色向量,其长度与矩阵的行数相等。(p.s. 标准颜色的名称与RGB数值对照表可以在这个网站找到:tool.oschina.net/common

barplot(height = c(6, 4, 8),  # 绘图数据(数值型向量)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = 'orange',  # 填充颜色
        border = '#ffffff')  # 轮廓颜色
barplot(height = matrix(1:6, ncol = 3, nrow = 2),  # 绘图数据(矩阵)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = c('orange', 'steelblue'),  # 填充颜色
        border = '#ffffff')  # 轮廓颜色

4. mainxlabylab:标题、X/Y轴名称

这四个参数很好理解,数据类型也为字符串类型,如果字符串太长想要换行的话,可以在换行的地方加上"\n"

barplot(height = c(6, 4, 8),  # 绘图数据(数值型向量)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = 'orange',  # 填充颜色
        border = '#ffffff', # 轮廓颜色
        xlab = '性别',  # X轴名称
        ylab = '频数',  # Y轴名称
        main = '性别分布条形图')  # 主标题

5. horiz:是否为水平放置

horiz的含义为是否将条形图水平放置,是逻辑参数(是或否)。其默认为FALSE,因此之前绘制的条形图均为垂直放置,然而当柱子数量过多时有必要将其旋转至水平:

barplot(height = c(6, 4, 8),  # 绘图数据(数值型向量)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = 'orange',  # 填充颜色
        border = '#ffffff', # 轮廓颜色
        xlab = '频数',  # X轴名称
        ylab = '性别',  # Y轴名称
        main = '性别分布条形图',  # 主标题
        horiz = TRUE,  # 是否为水平放置
       )

6. xlimylim:坐标轴取值范围

顾名思义,xlimylim用于限定坐标轴的取值范围,其数据类型为一个长度为二的数值型向量,分别代表取值范围的上界和下界。当horizTRUE时应修改xlim来控制柱子的高度,而当horizFALSE时则应修改ylim来控制柱子的高度。

# 当`horiz`为`TRUE`时修改`xlim`
barplot(height = c(6, 4, 8),  # 绘图数据(数值型向量)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = 'orange',  # 填充颜色
        border = '#ffffff', # 轮廓颜色
        xlab = '频数',  # X轴名称
        ylab = '性别',  # Y轴名称
        main = '性别分布条形图',  # 主标题
        horiz = TRUE,  # 是否为水平放置
        xlim = c(0, 10), # X轴取值范围
       )
#当`horiz`为`FALSE`时修改`ylim`
barplot(height = c(6, 4, 8),  # 绘图数据(数值型向量)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = 'orange',  # 填充颜色
        border = '#ffffff', # 轮廓颜色
        xlab = '频数',  # X轴名称
        ylab = '性别',  # Y轴名称
        main = '性别分布条形图',  # 主标题
        horiz = FALSE,  # 是否为水平放置
        ylim = c(0, 10), # Y轴取值范围
       )

7. legend.text:图例文本

height参数为矩阵时,每一个柱子内部也被划分为了多个类别,那么该如何区分柱子内部每个类别的含义呢?这就要用到图例,图例文本legend.text为一个字符型向量,长度与每个柱子中的类别数目相等,表达了柱子内部每个类别的含义:

par(family = 'Kai')  # 更改全部绘图字体
barplot(height = matrix(6:1, ncol = 3, nrow = 2),  # 绘图数据(矩阵)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = c('orange', 'steelblue'),  # 填充颜色
        border = '#ffffff',   # 轮廓颜色
        xlab = '频数',  # X轴名称
        ylab = '性别',  # Y轴名称
        main = '性别分布条形图',  # 主标题
        horiz = FALSE,  # 是否为水平放置
        ylim = c(0, 12), # Y轴取值范围
        legend.text = c('华为', '小米')  # 图例文本
       )

8. beside:是否平行排列

height参数为矩阵时,如果不单独设置beside参数,那么每一个柱子内部会被划分为多个类别,或者换种说法,不同的类别“堆积”起来成为了一个柱子。如果我们希望不同的类别并列摆放而不是堆积起来,就需要使用beside参数,如果beside参数为TRUE,那么不同的类别就会并列摆放形成“一簇”柱子:

par(family = 'Kai')  # 更改全部绘图字体
barplot(height = matrix(6:1, ncol = 3, nrow = 2),  # 绘图数据(矩阵)
        names.arg = c('男', '女', '未知'),  # 柱子名称
        family = 'Kai',  # 中文字体
        col = c('orange', 'steelblue'),  # 填充颜色
        border = '#ffffff',   # 轮廓颜色
        xlab = '频数',  # X轴名称
        ylab = '性别',  # Y轴名称
        main = '性别分布条形图',  # 主标题
        horiz = FALSE,  # 是否为水平放置
        ylim = c(0, 6), # Y轴取值范围
        legend.text = c('华为', '小米'),  # 图例文本
        beside = TRUE  # 是否平行排列
       )

三、总结与评价

使用R语言自带的barplot()函数,可以方便地画出漂亮的柱状图,基本上可以满足我们的大部分需求。然而其仍存在着一定的不足,例如:

  • 无法方便地调整每一个柱子的宽度
  • 无法方便地在柱子顶端显示数据
  • 每个柱子内部的多类别“堆叠”时,无法直观地看出每个类别的占比

为了实现上述的高级功能,我们还是需要使用到第三方绘图工具ggplot2,关于如何使用ggplot2绘制柱状图,敬请期待我的下一篇文章。编程代码的学习总是痛苦的,希望本文可以为广大初学者们提供一定的帮助!

编辑于 2020-02-16 11:47