乐趣区

关于r:R语言之-ggplot-2-和其他图形

文章和代码曾经归档至【Github 仓库:https://github.com/timerring/dive-into-AI】或者公众号【AIShareLab】回复 R 语言 也可获取。

1. 初识 ggplot2 包

ggplot2 包提供了一套基于图层语法的绘图零碎,它补救了 R 根底绘图零碎里的函数不足一致性的毛病,将 R 的绘图性能晋升到了一个全新的境界。ggplot2 中各种数据可视化的根本准则完全一致,它将数学空间映射到图形元素空间。设想有一张空白的画布,在画布上咱们须要定义可视化的数据(data),以及数据变量到图形属性的映射(mapping)。

上面应用数据集 mtcars 作图。

该数据集摘自 1974 年的美国《汽车趋势》杂志,蕴含 32 辆汽车的燃油耗费、设计和性能等方面的 11 个指标:mpg(耗油量)、cyl(气缸数)、disp(排量)、hp(总功率)、drat(后轴比)、wt(车重)、qsec(四分之一英里用时)、vs(发动机类型)、am(传动形式)、gear(后退挡个数)和 carb(化油器个数)。咱们首先来摸索车重和耗油量的关系,将变量 wt 映射到 x 轴,变量 mpg 映射到 y 轴。

library(ggplot2)
p <- ggplot(data = mtcars, mapping = aes(x = wt, y = mpg)) 

在下面的命令里,aes 代表美学(aesthetics)元素,咱们把须要映射的变量都放在这个函数中。间接运行 p 失去的只是一个空白的画布,还须要定义用什么样的图形来示意数据。以 geom 结尾的一系列函数用于指定图形元素,包含点、线、面、多边形等。上面应用点(point)这种几何对象来展现数据,后果如下图所示。

p + geom_point()

除了坐标轴,还能够把变量映射到色彩(color)、大小(size)、形态(shape)等属性。

例如,为了展现不同传动形式下车重和耗油量的关系,咱们能够将变量 am 映射为色彩(下图左)或形态(下图右)。变量 am 在原数据集里是一个数值型变量(取值为 0 和 1),本质上它应该是一个分类变量,因而咱们先把它转换为一个二程度的因子。

library(gridExtra)
mtcars$am <- factor(mtcars$am)
p1 <- ggplot(data = mtcars, aes(x = wt, y = mpg, color = am)) + geom_point()
p2 <- ggplot(data = mtcars, aes(x = wt, y = mpg, shape = am)) + geom_point()
grid.arrange(p1, p2, nrow=1)

下面的图形都是原始数据的展现,有时候咱们须要对原始数据进行某种演绎后作图。例如,用上图中的散点拟合曲线。

ggplot(data = mtcars, aes(x = wt, y = mpg, color = am)) + geom_smooth()

函数 geom_smooth() 里的参数 method 默认值为“loess”,即 LOESS 部分加权回归

如果想换一种拟合曲线的办法,能够扭转参数 method 的值。例如,用直线回归

ggplot(data = mtcars, aes(x = wt, y = mpg, color = am)) + 
        geom_smooth(method = "lm")

下面两幅图中都有两条拟合线,那是因为咱们将变量 am 映射成了色彩属性。如果只想显示一条平滑线,就须要在 geom_point() 函数中独自设置色彩的映射,后果如下图所示。

ggplot(data = mtcars, aes(x = wt, y = mpg)) + 
        geom_point(aes(color = am)) +
        geom_smooth() 

当初咱们曾经有了“图层”的概念了。一个图层就像是一张玻璃纸,蕴含各种图形元素,咱们能够别离建设多个图层,而后把它们叠放在一起组成最终的显示成果。

函数 aes() 就像是 ggplot2 的大脑,负责美学设计,而泛滥的以 geom 结尾的函数就像是 ggplot2 的双手,负责将这些美学设计出现进去。ggplot2 包中有超过 30 个以 geom 结尾的函数,读者可通过该包的帮忙文档查看这些函数。映射只负责将变量关联到某个图形属性,并不负责具体的数值。例如,在上图中,咱们将变量 am 映射到色彩,但具体应用哪种颜色是 ggplot2 主动抉择的。如果想本人设定色彩,就须要应用标度(scale)函数了。

标度函数是图形细节的调节函数,好比电视机的遥控器,能够调节电视机的音量、画面、色调等属性。ggplot2 中有品种繁多的以 scale 结尾的标度函数,可用于管制图形的色彩、点的大小和形态等。例如,咱们能够用上面的标度函数手动设置须要的色彩,后果如下图所示。

ggplot(data = mtcars, aes(x = wt, y = mpg)) + 
        geom_point(aes(color = am)) +
        scale_color_manual(values = c("blue", "red")) +
        geom_smooth() 

ggplot2 包还能实现 lattice 包中的分组绘图性能,即分面(facet)。分面是将整个数据依照某一个或几个分类变量分成多个子集,而后用这些子集别离作图。例如,要将上图依照变量 am 的两个程度别离展现,能够应用上面的命令。绘图后果如下图所示。

ggplot(data = mtcars, aes(x = wt, y = mpg)) + 
        geom_point() +
        stat_smooth() +
        facet_grid(~ am)

ggplot2 包中的主题(theme)函数用于定义绘图的格调,例如画布的背景。下图是一个黑白主题画布背景示例:

ggplot(data = mtcars, aes(x = wt, y = mpg)) + 
        geom_point(aes(color = am)) +
        stat_smooth() +
        theme_bw()

除了 ggplot2 包自带的主题,还有一些扩大包提供了多种主题格调,例如 ggthemes 包、artyfarty 包等。应用这些包之前须要先装置,感兴趣的读者可自行摸索。
以上介绍了 ggplot2 包中的映射(mapping)、图形元素(geom)、标度(scale)、分面(facet)和主题(theme)等概念,并展现了它们的根本用法。接下来咱们将摸索用 ggplot2 包绘制罕用统计图形的办法。

2. 散布的特色

在摸索数据的过程中,最根本的伎俩就是察看单个变量的取值状况。对于连续型变量,能够绘制直方图或密度曲线图。

上面用之前提及的 MASS 包里的数据集 anorexia 作图。先加载数据并建设新变量 wt.change(体重扭转量,单位:lb)。

data(anorexia, package = "MASS")
anorexia$wt.change <- anorexia$Postwt - anorexia$Prewt

接下来,用 ggplot2 包绘制变量 wt.change 的直方图,代码如下:

library(ggplot2)
p1 <- ggplot(anorexia, aes(x = wt.change)) +
        geom_histogram(binwidth = 2, fill = "skyblue", color = "black") +
        labs(x = "Weight change (lbs)") +
        theme_bw()
p1

其中,参数 binwidth 用于设置组距,默认值为全距除以 30,在作图时能够尝试设置不同参数值以失去比较满意的后果。参数 fill 用于设置填充色。参数 color 用于设置矩形边框的色彩。咱们还能够将直方图和密度曲线同时展现,如下图所示。

p2 <- ggplot(anorexia, aes(x = wt.change, y = ..density..)) +
        geom_histogram(binwidth = 2, fill = "skyblue", color = "black") +
        stat_density(geom = "line",linetype = "dashed", size = 1) +
        labs(x = "Weight change (lbs)") +
        theme_bw()
p2

其中,“y = ..density..”用于设定 y 轴为频率(密度),stat_density() 是一种用于计算密度估计曲线的统计变换。

密度曲线还能用于对不同数据的散布进行比拟。例如,要比拟不同医治形式下体重扭转量的散布,输出上面的代码:

p3 <- ggplot(anorexia, aes(x = wt.change, color = Treat, linetype = Treat)) +
        stat_density(geom = "line", size = 1) +
        labs(x = "Weight change (lbs)") +
        theme_bw()
p3

下面的命令先将变量 Treat 映射为色彩和线型,再画出 3 种医治形式下的体重扭转量 wt.change 的密度曲线,如上图所示。

除了直方图和密度曲线图,箱线图也常常用于展现数值型变量的散布,尤其多用于各组之间散布的比拟。例如:

p4 <- ggplot(anorexia, aes(x= Treat, y = wt.change)) +
        geom_boxplot() +
        theme_bw()
p4

从上图能够看出,FT 组的体重扭转量要高于其余两组,然而差别的显著性须要通过统计学测验能力得出结论。

ggpubr 包提供了在平行箱线图上增加组间比拟的统计学差别的性能。该包是一个 ggplot2 的衍生包,能够生成用于论文发表的统计图形,值得医学钻研工作者摸索。上面在上图的根底上增加组间均值比拟的统计学差别。

library(ggpubr)
my_comparisons <- list(c("CBT", "Cont"), c("CBT", "FT"), c("Cont", "FT"))
p5 <- ggplot(anorexia, aes(x= Treat, y = wt.change)) +
        geom_boxplot() +
        stat_compare_means(comparisons = my_comparisons,
                           method = "t.test",
                           color = "blue") +
        theme_bw()
p5

上图中的 p 值是用 t 测验进行组间两两比拟失去的。另外,咱们还能够用 ggplot2 绘制与上图类似的小提琴图,后果如下图所示。

p6 <- ggplot(anorexia, aes(x= Treat, y = wt.change)) +
        geom_violin() +
        geom_point(position = position_jitter(0.1), alpha = 0.5) +
        theme_bw()
p6

3. 比例的形成

许多数据会波及比例的问题,提取比例信息能使咱们理解各个组成部分对于整体的重要性。比例的形成罕用条形图展现,例如:

library(vcd)
data(Arthritis)
ggplot(Arthritis, aes(x = Treatment, fill = Improved)) +
        geom_bar(color = "black") +
        scale_fill_brewer() +
        theme_bw()

上图被称为叠加条形图,是为了在一幅图中同时展示多个变量,图中的纵坐标是计数的相对大小。但有时候咱们更心愿察看绝对比例,这能够通过将参数 position 设为“fill”来实现,后果如下图所示。

ggplot(Arthritis, aes(x = Treatment, fill = Improved)) +
        geom_bar(color = "black", position = "fill") +
        scale_fill_brewer() +
        theme_bw()

咱们还能够把参数 position 设为“dodge”来将条形图并排搁置,如下图所示。

ggplot(Arthritis, aes(x = Treatment, fill = Improved)) +
        geom_bar(color = "black", position = "dodge") +
        scale_fill_brewer() +
        theme_bw()

4. 用函数 ggsave() 保留图形

函数 ggsave() 专门用于保留 ggplot2 包绘制的图形,该函数能够导出多种不同格局的图片。例如:

p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
ggsave("myplot.png", p)
ggsave("myplot.pdf", p)

下面的命令先创立了一幅散点图并把后果保留为 p,而后用函数 ggsave() 别离把这幅图形保留为 png 和 pdf 格局的文件。关上当前工作目录就能够看到这两个文件。

如果要把图片用于出版物中,咱们能够对图片的尺寸和分辨率等进行设置。例如,把下面的图形对象 p 保留为 tiff 格局,并设置图片的长和宽别离为 12cm 和 15cm,分辨率为 500 dpi,代码如下:

ggsave("myplot.tiff", width = 15, height = 12, units = "cm", dpi = 500)

2. 其余图形

2.1 金字塔图

金字塔图是一种背靠背式的条形图,罕用于展现钻研人群的人口构造,所以也称为人口金字塔图。DescTools 包里的 PlotPyramid() 函数,以及 epiDisplay 包里的 pyramid() 函数都能够用来绘制金字塔图。上面以 epiDisplay 包里的数据集 Oswego 为例绘制金字塔图,这里须要用到数据集里的两个变量 age 和 sex。

options(warn = -1)
library(epiDisplay)
data(Oswego)
pyramid(Oswego$age, Oswego$sex, col.gender = c(2, 4), bar.label = TRUE)

上图展现的是不同性别下各个年龄组的频数散布。函数 pyramid() 里有很多参数能够用于管制图形的细节展现,读者请查看该函数的帮忙文档并尝试扭转不同的参数设置以失去称心的输入成果。

2.2 横向堆栈条形图

在做流行病学考察时,常常须要在问卷上设置很多选择题。对于一组问题,能够应用 sjPlot 包里的函数 plot_stackfrq() 对不同选项的比例进行可视化。上面以该包里的数据集 efc 为例作图,这里须要用到其中的 9 个变量,它们别离对应问卷里的 9 个选择题。运行上面代码前请先装置 sjPlot 包。

library(sjPlot)
data(efc)
names(efc)

head(efc)

qdata <- dplyr::select(efc, c82cop1:c90cop9)
plot_stackfrq(qdata)

绘图后果如上图所示,咱们能够从图中获取每个问题的表述、答复的人数、不同选项的抉择的百分比等信息。

sjPlot 包里会集了很多用于可视化流行病学和社会科学畛域的数据的函数。应用这些函数可能轻松地绘制出既好看又实用的统计图形,值得读者进一步摸索。

3.3 热图

热图(heatmap)是将一个矩阵中的元素数值用不同色彩表白,并对矩阵的行或列进行档次聚类的一种色彩图。通过热图,咱们不仅能够间接察看矩阵中的数值散布情况,还能够晓得聚类的后果。对于聚类分析的进一步介绍参见第 10 章。热图常常使用在生物信息学数据分析中。以 RNA-seq 为例,热图能够直观地出现多样本或多个基因的全局表白量的变动,还能够出现多样本或多个基因表白量的聚类关系。

stats 包里的函数 heatmap() 可用于制作热图。上面以数据集 mtcars 为例介绍该函数的用法。因为该数据集里变量的测量尺度有较大差别,咱们首先须要用函数 scale() 把变量标准化。标准化后的变量组成的矩阵能够作为函数 heatmap() 的输出,绘图后果如下图所示。

data(mtcars)
dat <- scale(mtcars)
class(dat)
heatmap(dat)

3.4 三维散点图

后面提到的图形都是二维的,如果想对 3 个数值型变量的关系进行可视化,能够应用 scatterplot3d 包的 scatterplot3d() 函数,应用前请先装置该包。

函数 scatterplot3d() 提供的参数选项包含设置图形符号、突出显示、角度、色彩、线条、坐标轴和网格线等。上面以 datasets 包里的数据集 trees 为例阐明此函数的用法。该数据集蕴含 3 个数值型变量 Girth、Height 和 Volume。咱们别离以这 3 个变量为坐标轴绘制三维散点图,后果如下图所示。

library(scatterplot3d)
data(trees)
scatterplot3d(trees, type = "h", highlight.3d = TRUE, angle = 55, pch = 16)

下面函数 scatterplot3d() 中的参数 type 用于设置绘图的类型,默认为“p”(点),这里设为“h”,显示垂线段。参数 angle 用于设置 x 轴和 y 轴的角度。须要留神的是,用动态的三维散点图形容 3 个变量之间的关系时,可能会受到察看角度的影响。

3.5 小结

其余一些专门的图形,例如散点图矩阵、相干图、正态 QQ 图、生存曲线、聚类图、碎石图、ROC 曲线和 Meta 剖析森林图等,将会在后续章节中联合统计分析办法陆续介绍。在 R 的利用中,可视化是一个十分沉闷的畛域,新的包层出不穷。网站 The R Graph Gallery 收集了各种新鲜的图形以及相应的示例代码,值得对可视化感兴趣的读者关注。

退出移动版