R自带了很多画图函数,比如用plot函数可以画一维或二维数据的点图,hist可以画分布的直方图,boxplot可以画箱线图。
plot(mtcars$mpg, main = "") #点图(横坐标表示第几个数据,纵坐标为取值)
hist(mtcars$mpg, main = "") #直方图
boxplot(mtcars$mpg, main = "") #箱线图(展示上下四分位数、中位数)
如果画出的图只是给自己看,那只需要像上面这样简单的指令就可以了。但很多时候需要将可视化结果进行展示,以方便他人从数据中提取更多信息,所以一个完整的图通常需要包括以下元素:图名、坐标名、图例、注释等,并且要足够美观、有信息量。下面以直方图为例,演示如何在图中添加这些元素。
h <- hist(mtcars$mpg, col = "red", freq = F,
xlab = "Miles per Gallon", main = "hist of mpg")
lines(density(mtcars$mpg), col="blue", lwd=2) #加上密度曲线
#col选颜色
#freq=T表示展示频次,freq=F表示展示“密度”(频率/组距)
#xlab行名、ylab列名、main标题
在上面的代码中,可以看到,对于一个画好的图,使用lines函数可以加上一条线。
如果想将多个图整合成一个,可以使用par函数,通过mfcol参数指定画布的布局,然后依次画图,直到充满画布。例如,下面代码中,mfcol=c(1,2)表示接下来要画两个图,画布是一行两列的。
par(mfcol = c(1,2)) #指定布局(一行两列)
hist(mtcars$mpg, col = "red", freq = F,
xlab = "Miles per Gallon", main = "")
lines(density(mtcars$mpg), col="blue", lwd=2) #第一个图
hist(mtcars$mpg, main = "") #第二个图
反过来,如果是两行一列:
par(mfcol = c(2,1)) #指定布局(两行一列)
hist(mtcars$mpg, col = "red", freq = F,
xlab = "Miles per Gallon", main = "")
lines(density(mtcars$mpg), col="blue", lwd=2) #第一个图
hist(mtcars$mpg, main = "") #第二个图
与基础的R画图函数相比,ggplot2包可以快速实现相对复杂的数据可视化效果。一般来说,要用ggplot函数画一个图,需要以下要素:
下面以直方图为例展示逐级添加以上元素的过程。
如果只指定了数据集,只有空白背景。
suppressMessages(library(tidyverse))
ggplot(data = mtcars) #指定数据集
在指定数据集的基础上,通过aes函数指定了要映射在x轴上的变量是mpg,可以看到横轴出现了mpg,以及刻度线,但由于没有指定画图类型,所以没有图形输出。
ggplot(data = mtcars, aes(x = mpg)) #指定x轴映射mpg
在上面的基础上,用geom_histogram函数加上直方图,再用geom_density函数加上密度曲线。
ggplot(data = mtcars, aes(x = mpg)) +
geom_histogram(aes(y = ..density..), fill = "red",
color = "black", bins = 5, freq = TRUE) +
geom_density(color = "blue", lwd = 1)
#y=..density..表示y轴画的是“密度”(频率/组距)而不是频数
#fill表示填充颜色
#color表示边框颜色
#bins表示分成多少个区间
在上面的基础上,加上标题、坐标轴的标题,并且设置居中。
fig1 <- ggplot(data = mtcars, aes(x = mpg)) +
geom_histogram(aes(y = ..density..), fill = "red",
color = "black", bins = 5, freq = TRUE) +
geom_density(color = "blue", lwd = 1)+
ggtitle("Histogram with Imposed Density Curve")+ #加上标题
ylab("Density")+ #y轴标题
xlab("Miles per Gallon")+ #x轴标题
theme(plot.title = element_text(hjust = 0.5)) #标题居中
fig1
与前面不同,上面这段代码没有直接输出ggplot的结果,而是把结果(即一张图片)赋值为fig1,通过输出fig1得到图片。同样的,我们可以根据am变量的取值画出mpg的箱线图,赋值为fig2,然后尝试将两张图片合并成一张。
下面这段代码,是画分组箱线图的典型代码。应用场景为:探究某一连续型变量的分布在根据某个分类变量所确定的多个组中是否存在一定差异。比如,某个数据记录了某次考试中每个学生的性别、分数,我们想看男生女生这两个群体的分数的分布是否有所差异,就可以根据性别分成两组,分别画出箱线图。
下面的例子,就是在mtcars这个数据集中,根据am这个变量是mannual还是automatic分成两组,画出mpg变量在这两个组中的箱线图。各要素构成为:
mtcars$am <- factor(mtcars$am, labels = c("Mannual", "Automatic"))
fig2 <- ggplot(data = mtcars, aes(y = mpg, x = am)) +
geom_boxplot() +
ggtitle("Botplots of Miles per Gallon \n By Transmission Types") +
xlab("Transmission Types") +
ylab("Miles per Gallon")
fig2
将fig1和fig2合并成一张图,并指定画布的布局是一行两列。
library(cowplot)
plot_grid(fig1, fig2, nrow = 1) #nrow表示画布的行数
如果我们需要根据某个分类型变量分组,然后分别画图,还有一种更通用的方法,那就是使用facet_grid函数。下面代码演示了根据am变量分成两个数据集,然后再分别画出mpg的直方图,最后合并成一张图的流程。除了多加了facet_grid函数外,其余指令与在整个数据集上画mpg的直方图是相同的。
fig3 <- ggplot(data = mtcars, aes(x = mpg)) +
geom_histogram(aes(y = ..density..), fill = "Green",
color = "black", bins = 5) +
facet_grid(am ~ .) +
ggtitle("Histogram of Milles per Gallon \n By Tranmission Type")
fig3
facet_grid(am ~ .)表示根据am变量分组画图,将图片按行排列;反之,facet_grid(. ~ am)表示根据am变量分组画图,将图片按列排列:
fig4 <- ggplot(data = mtcars, aes(x = mpg)) +
geom_histogram(aes(y = ..density..), fill = "Green",
color = "black", bins = 5) +
facet_grid(. ~ am) +
ggtitle("Histogram of Milles per Gallon \n By Tranmission Type")
fig4