「R」数据可视化4 : 直方图/条形图

2020-07-06 17:11:08 浏览数 (1)

本文作者蒋刘一琦,自嘲是一个有艺术追求的生信狗,毕业于浙江大学生物信息学专业,目前在复旦大学就读研究生,研究方向为宏基因组。

在生物信息领域我们常常使用R语言对数据可视化。在对数据可视化的时候,我们需要明确想要展示的信息,从而选择最为合适的图突出该信息。本系列文章将介绍多种基于不同R包的作图方法,希望能够帮助到各位读者。

什么是直方图/条形图?

直方图和条形图看起来没有什么区别,长得很像,但是这两者并不同一种统计图像。具体来说,通常直方图用来描述连续型数据,比如年龄、身高、体重等。而条形图通常用来描述分类型数据,比如性别、国家等。

对于直方图,我们要做的第一步就是把连续性的数据分箱(bin),所谓的分箱实际上就是将数据按照一定的间隔进行分组。比如我们现在手上有100个人的年龄的数据,从20岁到60岁,然后我们以10岁为间隔,分别统计20-30、30-40、40-50、50-60岁这四组的人数,再进行绘图。因此不同组之间通常是连续的,且间隔一致。数据的连续性体现在图像上就是柱子之间并没有间隔。因此,直方图可以粗略地表示出数据分布密度,被用于密度估计。

直方图例子

而条形图如下列例子统计了不同国家的样本数量。可以看到下图的柱子之间有间隔,体现出国家并非一个连续变量而是一个分类变量。

条形图例子

直方图/条形图怎么画?

ggplot2提供了绘制直方图和条形图的功能,分别为geom_bar()geom_histogram()。具体如下:

代码语言:javascript复制
geom_histogram(mapping = NULL, data = NULL, stat = "bin",
    position = "stack", ...)
geom_bar(mapping = NULL, data = NULL, stat = "count",
  position = "stack", ...,)

那么这两个函数是否有区别吗?实际上并没有太大的区别,geom_histogram()等同于geom_bar() stat_bin()

如何绘制直方图/条形图

1)需要什么格式的数据

本次我们来看一个新的R提供的数据,就是闪闪发光的钻石?Diamonds。

数据集Diamonds

price:钻石的价格,单位美元

carat:钻石的重量,单位克拉

cut:钻石切割的质量水平,Fair, Good, Very Good, Premium, Ideal

color:钻石的颜色,从J(最差)到D(最好)

clarity:钻石的净度,I1(最差)SI2, SI1, VS2, VS1, VVS2, VVS1, IF (最好)

x:长度,单位mm

y:宽度,单位mm

z:深度,单位mm

我们探讨两个问题——统计表中所有的钻石(大约 50,000个)的重量分布以及净度。可以看到重量是一个连续型变量,而净度是一个分类型变量。所以前者我们做直方图,后者我们做条形图。

2)如何使用ggplot2做直方图

首先我们来看看钻石重量的直方图。

代码语言:javascript复制
#加载包
library(ggplot2)
#作图
ggplot(diamonds, aes(carat))  
  geom_histogram()

输入上述命令后我们会得到一条提示stat_bin() using “bins = 30”. Pick better value with “binwidth”.什么意思呢?就是把所有的数据按照相同间隔分成了30组,图上有30个柱子。(如图)

从图上我们可以看到大部分的钻石都是1克拉以下,较少的钻石是2克拉以上。那用geom_bar()会怎么样呢?我们来看一看。

代码语言:javascript复制
ggplot(diamonds, aes(carat))  
  geom_bar()

可以看到如果使用上述命令,每一个重量对应的都有一个柱子,显示了不同重量而非某个范围的重量所对应的钻石数量。刚刚我们说了geom_bar() stat_bin()才是等同于geom_histogram()。所以我们来看一下如果命令变成下述是怎么样的?

代码语言:javascript复制
ggplot(diamonds, aes(carat))  
  geom_bar(stat='bin')

看,就和刚才一模一样了!

3)如何使用ggplot2做条形图

然后我们来瞧瞧条形图。

代码语言:javascript复制
#加载包
library(ggplot2)
#作图
ggplot(diamonds, aes(clarity))  
  geom_bar()

从图中我们可以看到不同等级净度的钻石情况。

4)如何做好看的直方/条形图

利用下述代码我们可以得到不同重量的钻石切割水平的情况。

代码语言:javascript复制
ggplot(diamonds, aes(carat,fill=cut))  
  geom_histogram(bins = 20,color='black') #分为20个组,添加边框
  theme_bw() 
  theme(
    panel.grid = element_blank()#去除背景的分割线
  ) 
  scale_fill_manual(values=brewer.pal(5,'Blues'))

利用下述代码我们可以得到横向的条形图。

代码语言:javascript复制
ggplot(diamonds, aes(clarity,fill=clarity))  
  geom_bar() 
  theme_bw() 
  theme(
    panel.grid = element_blank()
  ) 
  coord_flip()#转为横向

关于直方/条形图的介绍就到这里啦。大家还可以更进一步的看一看这两个绘图函数的功能,让图像变得更好看。

0 人点赞