【r<-高级|实战|绘图】ggplot2高级绘图

以三个数据集解释ggplot2的使用。第一个是lattice包中的singer数据集,它包括纽约合唱团歌手的高度和语音变量。第二个是mtcars数据集,它包含32辆汽车的详细信息。最后一个是car包中的Salaries数据集,它包含大学教授的收入信息,并用来探索性别差异对它们收入的影响。这些数据集提供了各种可视化的挑战。

ggplot2包介绍

在ggplot2中,图是采用串联起来(+)号函数创建的。每个函数修改属于自己的部分。也就是说,每个函数完成图中各个组件的相应功能,然后通过串联+号将其连接起来,形成一个完整的图形。

> library(ggplot2)
> ggplot(data=mtcars, aes(x=wt, y=mpg)) + 
+       geom_point() + 
+       labs(title="Automobie Data", x="Weight", y="Miles Per Gallon")
【r<-高级|实战|绘图】ggplot2高级绘图_第1张图片
Scatter Plot between weight and miles of Cars.png

分解上述图形的制作步骤:

ggplot()初始化图形并指定要用到的数据来源和变量。aes()函数的功能是指定每个变量扮演的角色(aes代表aesthetics,即如何用视觉形式呈现信息)。在这里,变量wt的值映射到x轴,mpg的值映射到y轴。

ggplot函数设置图形但没有自己的视觉输出。使用一个或多个几何函数向图中添加了几何对象(简写为geom),包括点、线、条、箱线图和阴影区域。在上述例子中,geom_point()函数在图形中画点,创建了一个散点图。labs()函数是可选的,可以添加注释、轴标签、标题等。

ggplot2中有很多函数,并且大多数包含可选的参数。下面我们来看一下相应扩展。

> png('Scatter plot 2.png')
> ggplot(data=mtcars, aes(x=wt, y=mpg)) + 
+     geom_point(pch=17, color='blue', size=2) +
+     geom_smooth(method='lm', color='red', linetype=2) + 
+     labs(title="Automobile Data", x="Weight", y="Miles Per Gallon")
> dev.off()

![Uploading Automobile Data by Engine Type_988673.png . . .]

【r<-高级|实战|绘图】ggplot2高级绘图_第2张图片
Scatter plot 2.png

我们依据对最初图形的解释,可以很清晰的观察到不同的函数执行了什么样的功能。

ggplot2包提供了分组和小面化的方法。分组指的是在一个图形中显示两组或多组观察结果。小面化指的是在单独、并排的图形上显示观察组。需要注意,ggplot2包在定义组或面时使用因子。

这里我们使用mtcars数据集查看分组和面,并进行绘图。

【r<-高级|实战|绘图】ggplot2高级绘图_第3张图片
Automobile Data by Engine Type.png
# 将变量转换为因子
mtcars$am <- factor(mtcars$am, levels=c(0,1), labels=c("Automatic", "Manual"))
mtcars$vs <- factor(mtcars$vs, levels=c(0,1), labels=c("V-Engine", "Straight Engine"))
mtcars$cyl <- factor(mtcars$cyl)

library(ggplot2)
# 绘图
ggplot(data=mtcars, aes(x=hp, y=mpg, shape=cyl, color=cyl)) + 
    geom_point(size=3) +
    facet_grid(am~vs) +
    labs(title="Automobile Data by Engine Type", x="Horsepower", y="Miles Per Gallon")

在本例中,amvs是刻度变量,cyl是分组变量。

用几何函数指定图的类型

ggplot()函数指定要绘制的数据源和变量,几何函数则指定这些变量如何在视觉上进行表示。目前,有37个几何函数可供使用。以下列出常用的函数。

函数 添加 选项
geom_bar() 条形图 color, fill, alpha
geom_boxplot() 箱线图 color, fill, alpha, notch, width
geom_density() 密度图 color, fill, alpha, linetype
geom_histogram() 直方图 color, fill, alpha, linetype, binwidth
geom_hline() 水平线 color, aplha, linetype, size
geom_jitter() 抖动点 color, size, alpha, shape
geom_line() 线图 colorvalpha, linetype, size
geom_point() 散点图 color, alpha, shape, size
geom_rug() 地毯图 color, sides
geom_smooth() 拟合曲线 method, formula, color, fill, linetype, size
geom_text() 文字注解 这个非常多,参考相应文档
geom_violin() 小提琴图 color, fill, alpha, linetype
geom_vline() 垂线 color, alpha, linetype, size

关于几何函数的常见选项

选项 详述
color 对点、线和填充区域的边界进行着色
fill 对填充区域着色,如条形和密度区域
alpha 颜色的透明度,从0(完全透明)到1(不透明)
linetype 图案的线条(1=实线,2=虚线,3=点,4=点破折号,5=长破折号,6=双破折号)
size 点的尺寸和线的宽度
shape 点的形状(和pch一样,0=开放的方形,1=开放的圆形,2=开放的三角形,等等)
position 绘制诸如条形图和点等对象的位置。对条形图来说,'dodge'将分组条形图并排,'stacked'堆叠分组条形图,'fill'垂直地堆叠分组条形图并规范其高度相等。对于点来说,'jitter'减少点重叠。
binwidth 直方图的宽度
notch 表示方块图是否应为缺口(TRUE/FALSE)
sides 地毯图的安置("b"=底部, "l"=左部,"t"=顶部,"r"=右部,"bl"=左下部,等等)
width 箱线图的宽度

下面举个例子来验证一下以上参数的使用:

data(Salaries, package='car')
library(ggplot2)
ggplot(Salaries, aes(x=rank, y=salary)) +
        geom_boxplot(fill="cornflowerblue",
                     color="black", notch = TRUE) +
        geom_point(position='jitter', color='blue', alpha=0.5) + 
        geom_rug(sides='l', color='black')
【r<-高级|实战|绘图】ggplot2高级绘图_第4张图片
Salaries by Rank.png

该图显示了不同学术地位对应薪水的缺口箱线图。实际的观察值(教师)是重叠的,因而给予一定的透明度以避免遮挡箱线图。它们还抖动以减少重叠。最后,一个地毯图设置在左侧以指示薪水的一般扩散。

当几何函数组合形成新类型的图时,ggplot2包的真正力量就会得到展示,让我们利用singer数据集再来一探究竟。

library(ggplot2)
data(singer, package = "lattice")
ggplot(singer, aes(x=voice.part, y=height)) +
        geom_violin(fill="lightblue") + 
        geom_boxplot(fill="lightgreen", width=.2)
【r<-高级|实战|绘图】ggplot2高级绘图_第5张图片
singer_combine_fig.png

箱线图展示了在singer数据框中每个音部的25%,50%,75%分位数得分和任意的异常值。对于每个声部身高范围上的得分分布,小提琴图展示了更多视觉线索。

接下来我们将使用几何函数创建广泛的图表类型。让我们从分组开始吧——在一个图中展示多个分组观察值。

分组

在R中,组通常用分类变量的水平(因子)来定义。

分组是通过ggplot2图将一个或多个带有诸如颜色、形状、填充、尺寸和线条类型的视觉特征的分组变量来完成的。ggplot()声明中的aes()函数负责分配变量(图形的视觉特征)。

我们依旧以Salaries数据集来进行相关探索。

首先,查看薪水是如何随学术等级变化的:

data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=salary, fill=rank)) + 
        geom_density(alpha=.3)
【r<-高级|实战|绘图】ggplot2高级绘图_第6张图片
Salaries density by Rank.png

接下来,我们通过性别和学术等级分组,绘制获得博士学位年数和薪水的关系:

ggplot(Salaries, aes(x=yrs.since.phd, y=salary, color=rank, shape=sex)) +
        geom_point()
【r<-高级|实战|绘图】ggplot2高级绘图_第7张图片
Salaries by phd.png

最后,我们可以用一个分组的条形图按学术等级和性别来可视化教授的人数(三种条形图方式):

【r<-高级|实战|绘图】ggplot2高级绘图_第8张图片
Number by Rank1.png
【r<-高级|实战|绘图】ggplot2高级绘图_第9张图片
Number by Rank2.png
【r<-高级|实战|绘图】ggplot2高级绘图_第10张图片
Number by Rank3.png

值得注意的是,第三个图形中y轴的标签是错误的,它应该是比例而不是数量。我们可以通过添加y="proportion"参数到labs()函数来解决。

选项可以通过不同的方式使用,这取决于它们发生在aes()函数的内部还是外部。通常来说,变量应该设在aes()函数内,分配常数应该在aes()函数外

刻面

如果组在图中并排出现而不是重叠为单一的图形,关系就是清晰的。我们可以使用facet_wrap()函数和facet_grid()函数创建网格图形(在ggplot2中也称为刻面图)。下表给出了相关的语法,var,rowvar,colvar是因子。

语法 结果
facet_wrap(~var, ncol=n) 将每个var水平排列成n列的独立图
facet_wrap(~var, nrow=n) 排成n行独立图
facet_grid(rowvar~colvar) rowvar和colvar组合的独立图
facet_grid(rowvar~.) 每个rowvar水平的独立图,配置成一个单列
facet_grid(.~colvar) 每个colvar水平的独立图,配置成单行

3个例子

data(singer, package = 'lattice')
library(ggplot2)
ggplot(data=singer, aes(x=height)) + 
        geom_histogram() +
        facet_wrap(~voice.part, nrow=4)

ggplot(data=singer, aes(x=height)) + 
        geom_density() +
        facet_grid(voice.part~., nrow=4)


data(Salaries, package='car')
library(ggplot2)
ggplot(Salaries, aes(x=yrs.since.phd, y=salary, color=rank, shape=rank))+
        geom_point() + facet_grid(.~sex)

添加光滑曲线

这一部分我们着重分析一下添加平滑曲线到散点图的方法。

我们可以使用geom_smooth()函数来添加一系列的平滑曲线和置信区域。函数的参数参考下表:

选项 描述
method= 使用的平滑函数。允许的值包括lm, glm, smooth, rlm, glm,分别对应线性、广义线性、loess、健壮线和广义相加模型。smooth是默认值
formula= 在光滑函数中使用的公式。例子包括y~x, y~log(x), y~poly(x,n), y~ns(x)
se 绘制置信区间(TRUE/FALSE)默认为TRUE
level 使用的置信区间水平(默认为95%)
fullrange 指定拟合应涵盖全图(TRUE),或仅仅是数据(FALSE)。默认为FALSE

使用Salaries数据集,忽略性别和学术等级,我们先检验博士毕业年数和薪水之间的关系。

data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=yrs.since.phd, y=salary)) +
        geom_smooth() + geom_point()
【r<-高级|实战|绘图】ggplot2高级绘图_第11张图片
Salaries by yrs.png

统计函数

​ ggplot2包中含有大量统计函数来计算所需的量,从而生产更多的可视化数据。通常情况下,几何函数隐式地调用统计函数,我们不需要直接处理这些问题。不过指导它们的存在是有用的。

修改ggplot2图形的外观

R的基础绘图中,使用par()函数或特定的画图函数的图形参数来自定义基本函数。遗憾的是,这些对ggplot2图形没有影响,该包提供了特定了函数来改变其图形的外观。

坐标轴

ggplot2包会自动生成基本所需要的图形参数。当我们需要更大程度定制时,需要了解相应函数的用法。我们已经知道labs()函数可以用来添加标题并改变坐标轴标签,让我们再看看其他的有用函数:

函数 选项
scale_x_continuous()和scale_y_continuous() breaks=指定刻度标记、labels=指定刻度标记标签、limits=控制要展示的值的范围
scale_x_discrete()和scale_y_discrete() breaks=对因子的水平进行放置和排序,labels=指定这些水平的标签,limits=表示哪些水平应该展示
coord_filp() 颠倒x轴和y轴

我们将这些函数应用一个分组箱线图中,其中包含按学术等级和性别分组的薪资水平,代码如下:

data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=rank, y=salary, fill=sex)) +
    geom_boxplot() +
    scale_x_discrete(breaks=c('AsstProf', 'AssocProf', 'Prof'),
                     labels=c('Assistant\nProfessor',
                              "Associate\nProfessor",
                              "Full\nProfessor")) + 
    scale_y_continuous(breaks = c(50000, 100000, 150000, 200000),
                       labels=c('$50K','$100K','$150K','$200K')) + 
    labs(title="Faculty Salary by Rank and Sex", x='', y='')
【r<-高级|实战|绘图】ggplot2高级绘图_第12张图片
Faculty Salary by Rank and Sex.png

图例

图例是指如何用颜色、形状、尺寸等视觉特征表示数据特征的指南。标题和位置是最常用的定制特征。

当更改图例的标题时,必须综合考虑颜色、填充、尺寸等等。可以通过fill="mytitle"加到labs()函数中来改变标题。

标题的位置由theme()函数中的legen.position选项控制。可能的值包括left, top, right(默认), bottom。我们也可以在图中给定的位置指定一个二元素向量。

使用添加修改上一个图的代码对图形展示效果进行修改:

    labs(title="Faculty Salary by Rank and Sex", x='', y='',fill='Gender')
    theme(legend.position=c(.1,.8)) # 图例的左上角分别距离左侧边缘10%,底部边缘80%

标尺

ggplot2包使用标尺把数据空间的观察值映射到可视化的空间中。标尺可以连续也可以离散。

在ggplot2中标尺的概念很普遍,可以通过查看以scale_开头的函数来了解更多信息。

主题

主题可以让我们控制这些图的整体外观。theme()函数中的选项可以让我们调整字体、背景、颜色和网格线等。主题可以使用一次,也可以保存起来应用到多个图中。尝试探索以下代码:

data(Salaries, package = 'car')
library(ggplot2)
mytheme <- theme(plot.title=element_text(face="bold.italic",
                                         size = "14", color = "brown"),
                 axis.title=element_text(face="bold.italic", size=10,
                                         color="brown"),
                 axis.text=element_text(face="bold", size=9,
                                        color="darkblue"),
                 panel.background = element_rect(fill="white",
                                                 color="darkblue"),
                 panel.grid.major.y=element_line(color="grey",
                                                 linetype = 2),
                 panel.grid.minor.y=element_line(color="grey",
                                                 linetype=2),
                 panel.grid.minor.x=element_blank(),
                 legend.position = "top")

ggplot(Salaries, aes(x=rank,y=salary,fill=sex)) +
        geom_boxplot() + 
        labs(title="Salary by Rank and Sex", x="Rank", y="Salary") +
        mytheme
【r<-高级|实战|绘图】ggplot2高级绘图_第13张图片
mytheme.png

多重图

​ 基础绘图中,我们使用图形参数mfrow和基本函数layout()把两个或多个基本图放到单个图中,同样,这种方法在ggplot2中不适用。将多个ggplot2包的图形放到单个图形中最简单的方式是使用gridExtra包中的grid.arrange()函数。我们需要事先安装这个包。

让我们创建3个ggplot2图并把它放在单个图形中。

data(Salaries, package = 'car')
library(ggplot2)
p1 <- ggplot(data=Salaries, aes(x=rank)) + geom_bar()
p2 <- ggplot(data=Salaries, aes(x=sex)) + geom_bar()
p3 <- ggplot(data=Salaries, aes(x=yrs.since.phd, y=salary)) + geom_point()

library(gridExtra)
grid.arrange(p1,p2,p3,ncol=3)
【r<-高级|实战|绘图】ggplot2高级绘图_第14张图片
multiple pic.png

注意截面图(刻面图)和多重图的区别。

保存图形

可以使用标准方法来保存创建的图形,也可以使用ggsave()函数更方便保存它们。它的选项包括保存哪幅图形,保存在哪里和以什么形式保存。例如

myplot <- ggplot(data=mtcars, aes(x=mpg)) + geom_histogram()
ggsave(file="mygraph.png",plot=myplot,width=5,height=4)

myplot保存为5英寸X4英寸PNG格式。我们可以通过设置文件拓展名为ps, tex, jpeg, pdf, tiff, png, bmp, svg, wmf来保存为不同格式。

如果忽略plot=选项,最近创建的图形会被保存。更多细节参考help(ggsave)

参考:R实战

你可能感兴趣的:(【r<-高级|实战|绘图】ggplot2高级绘图)