前面我们介绍了用R语言的ggplot2包绘制常见的条形图、折线图、散点图、分布图、饼图和地图,大体都知道了如何绘制这些图形,但没有重点介绍如何再修饰一下这些图,如添加参考线、注释、添加图形标题、坐标轴标签设置等。下文就针对这些内容进行详细讲解。


一、为图形添加注释

有时在图形中添加适量的注释,将会使阅读者更快速的了解图形表达的含义。ggplot2包中的annotate()函数帮助用户给图形的指定位置添加注释,一般注释可以从点、线和面的角度进行修饰,对应的geom参数可以是text/segment/pointrange/rect。下面就举几个例子,让大家看看注释带来的好处。

library(ggplot2)

SH_GDP <- read.csv(file = file.choose())


#不作任何修饰的折线图

p0 <- ggplot(data = SH_GDP, mapping = aes(x = Year, y = GDP)) + geom_line(colour = 'blue', size = 1) + geom_point(colour = 'red', size = 2)

p0

基于ggplot2图形的微调_坐标轴


一般统计图形至少包括4个元素,即图形标题、坐标轴标签、图例和数据来源。就上面这幅图而言,缺失了标题和数据来源的注释,下面分别为图形加上这两项内容。

#可以使用labs()函数或ggtitle()函数为图形添加标题

p1 <- p0 + labs(title = '上海近20年GDP走势')

#或者p1 + ggtitle(label = '上海近20年GDP走势')

p1

基于ggplot2图形的微调_坐标轴_02


#使用annotate()函数为图形添加数据来源信息

p2 <- p1 + annotate(geom = 'text', x = 2012, y = 2500, label = '数据来源:中国统计局', colour = 'brown')

p2

基于ggplot2图形的微调_数据_03


好,图形的标题和数据来源的注释已添加完毕,如果我还想为2008年GDP上升缓慢添加注释,该如何做到?

p3 <- p2 + annotate(geom = 'rect', xmin = 2008, ymin = 12500, xmax = 2009, ymax = 17500, alpha = 0.4) + annotate('segment', x = 2010, y = 10000, xend = 2008.5, yend = 14500, size = 1.2, arrow = arrow()) + annotate('text', x = 2010, y = 10000, label = '受2008年金融危机影响', colour = 'red')

p3

基于ggplot2图形的微调_5e_04

上图在原来的基础上添加了2008~2009之间的阴影矩阵,同时添加带有箭头的线,并注释了2008~2009年GDP上升缓慢的原因。


为了比较前10年与后10年上海GDP总量变化情况,可以添加如下形式的注释:

p4 <- p3 + geom_vline(xintercept = 2004.5, colour = 'orange', size = 1, linetype = 2) + annotate('text', x = 2008, y = 20000, label = '后10年GDP约为前10年GDP总和的3.5倍') 

p4

基于ggplot2图形的微调_坐标轴_05

虽然上面的图有些画蛇添足的意思,但这其中包含了如下4中注释:

1)添加阴影矩阵(rect),框出重点关注区域

2)通过带箭头的射线(segment),指出需要注释的地方

3)在指定点的位置添加文本型(text)注释内容


尽管annotate()函数和geom_text()函数都可以问生成的图形添加文本,但其工作原理是有很大差异的。annotate()函数只会向图中添加一个单独的文本对象,而geom_text()函数却会根据数据创建许多的文本对象(同样是一条文本对象,但数据中有多少点(观测)就会重叠添加文本对象多少次)。例如:

ggplot(data = SH_GDP, mapping = aes(x = Year, y = GDP)) + geom_line(colour = 'blue', size = 1) + geom_point(colour = 'red', size = 2) + annotate('text', x = 2000, y = 20000, label = '测试annotate注释', alpha = 0.5)

基于ggplot2图形的微调_5e_06


ggplot(data = SH_GDP, mapping = aes(x = Year, y = GDP)) + geom_line(colour = 'blue', size = 1) + geom_point(colour = 'red', size = 2) + geom_text( x = 2005, y = 20000, label = '测试geom_text注释', alpha = 0.5)

基于ggplot2图形的微调_5e_07


看到区别了吗?同样为0.5的透明度,一个浅,一个深,深是因为该文本对象'测试geom_text注释'重叠了20次。


如果我的图形中需要添加数学表达式,该如何实现呢?其实很简单,只需两步:

1)了解R中是如何表示数学函数的,可通过?plotmath查看数学表达式如何在R中显示

2)annotate()函数将parse设为TRUE即可

下面举一个例子:

#标准正态分布曲线

x <- seq(from = -5, to = 5, length = 1000)

y <- dnorm(x)

ggplot(data = NULL, mapping = aes(x = x, y = y)) + geom_line(colour = 'blue', size = 2) + annotate('text', x = 0, y = 0.1, label = 'f(x) == frac(1,sqrt(2*pi))*e^(-frac(x^2,2))', parse = TRUE, size = 5, colour = 'red')

基于ggplot2图形的微调_坐标轴_08


二、为图形添加参考线

geom_abline()、geom_hline()和geom_vline()函数可以为图形添加斜线、水平线和垂直线,必要时这样的参考线还是值得使用的,例如添加一条平均水平或垂直线。

set.seed(1234)

type <- c('A','B','C','D','E','F','G')

value <- runif(7, min = 10, max = 100)

df <- data.frame(type = type, value = value)


ggplot(data = NULL, mapping = aes(x = type, y = value)) + geom_bar(stat = 'identity', fill = 'steelblue', colour = 'black') + geom_hline(yintercept = mean(df$value), linetype = 2, col = 'red', size = 1) + annotate('text', x = 'A', y = mean(df$value) + 3, label = paste('平均值:',round(mean(df$value),2)))

基于ggplot2图形的微调_坐标轴_09


三、旋转坐标轴

正如上面的条形图所示,该条形图是水平放置的,如果我想让条形图垂直放置(比较建议这样做,因为水平放置一般是跟时间趋势相关的),该如何实现呢?很简单,只需添加coord_flip()函数就可以实现,是不是觉得ggplot2太伟大了?

ggplot(data = NULL, mapping = aes(x = reorder(type, value), y = value)) + geom_bar(stat = 'identity', fill = 'steelblue', colour = 'black') + geom_hline(yintercept = mean(df$value), linetype = 2, col = 'red', size = 1) + annotate('text', x = 'A', y = mean(df$value) + 3, label = paste('平均值:',round(mean(df$value),2))) + xlab('type') + coord_flip()

基于ggplot2图形的微调_数据_10


四、修改刻度标签的内容

如果坐标轴标签值非常大,如3000000如何改写为'3M'呢?或如何将千、万、亿值中加入千分位逗号?下面举一个例子以说明这两种情况:

library(scales)

set.seed(1234)

x <- runif(1000,min = 1000, max = 10000)

y <- runif(1000, min = 1000000, max = 10000000)

#坐标轴标签不加任何处理

ggplot(data = NULL, mapping = aes(x = x, y = y)) + geom_point()

基于ggplot2图形的微调_数据_11

注意,使用comma函数时,必须先加载scales包。

#将x轴处理成含千分位逗号的格式,将y轴处理为M格式的

ggplot(data = NULL, mapping = aes(x = x, y = y)) + geom_point() + scale_x_continuous(breaks = seq(2500, 10000, 2500), labels = comma(seq(2500, 10000, 2500))) + scale_y_continuous(breaks = seq(2.5e+06, 1.0e+07, 2.5e+06), labels = paste(seq(2.5, 10, 2.5), 'M', sep = ''))

基于ggplot2图形的微调_数据_12


有时会遇到一种尴尬的情况:类别型变量水平的名称太长,导致刻度标签显示非常难看,该如何解决呢?下面的例子一看你就明白了。

set.seed(1234)

level_labels <- c('good morning', 'the weather is good', 'this is my teacher', 'my name is snake', 'what is your name', 'r language is easy to learn')

type <- sample(level_labels, size = 1000, replace = TRUE)

values <- c(rnorm(250), rt(250,3), rf(250,2,3), runif(250,3,5))

#不作任何调整的刻度标签

ggplot(data = NULL, mapping = aes(x = type, y = values)) + geom_boxplot()

基于ggplot2图形的微调_坐标轴_13


#对于这种情况,可以选择刻度标签的角度,使其看起来比较舒服

ggplot(data = NULL, mapping = aes(x = type, y = values)) + geom_boxplot() + theme(axis.text.x = element_text(angle = 30, vjust = .8))

基于ggplot2图形的微调_数据_14


五、修改坐标轴标签的内容

默认情况下,坐标轴标签会根据ggplot()中aes()属性值自动为坐标轴附上标签,可以通过labs()函数、xlab()函数、ylab()函数、scale_x_*函数、scale_y_*函数和theme()函数实现。这里重点讲一下scale_x_*函数、scale_y_*函数和theme()函数的搭配使用,该函数非常的灵活,可以对坐标轴标签、刻度标签和刻度标记等进行修饰。

ggplot(data = NULL, mapping = aes(x = type, y = values)) + geom_boxplot() + scale_x_discrete(name = 'Long level') + theme(axis.text.x = element_text(angle = 30, vjust = .8, colour = 'red', size = 10), axis.title.x = element_text(colour = 'blue', size = 16))

基于ggplot2图形的微调_5e_15


六、修改图形标题的外观

讲完了图形注释、坐标轴和刻度的修饰,最后再来讲讲如何修改图形标题的外观,这里仍然使用的是them()函数,可见该函数有多强大了。

ggplot(data = SH_GDP, mapping = aes(x = Year, y = GDP)) + geom_line(colour = 'blue', size = 1) + geom_point(colour = 'red', size = 2) + labs(title = '上海近20年GDP走势') + theme(plot.title = element_text(colour = 'brown', size = 20, face = 'bold'))

基于ggplot2图形的微调_坐标轴_16

这样就可以非常方便的修改坐标轴标签、刻度标签和图形标题的外观和内容,这不是一件令人振奋的事吗?

到这里,我认为比较常用和重要的内容基本完成,在回顾一下几个重要的函数:

annotate()

labs()

xlab()

ylab()

ggtitle()

scale_x_*()

scale_y_*()

theme()

coord_flip()


文中涉及到的数据和脚本下载链接:

https://yunpan.cn/crtEbbiMhGRvG  访问密码 14fc


参考文献:

R语言_ggplot2:数据分析与图形艺术

R数据可视化手册