# Multiple plot function ggplot objects can be passed in ..., or to plotlist
# (as a list of ggplot objects) - cols: Number of columns in layout -
# layout: A matrix specifying the layout. If present, 'cols' is ignored.  If
# the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE), then
# plot 1 will go in the upper left, 2 will go in the upper right, and 3 will
# go all the way across the bottom.
multiplot <- function(..., plotlist = NULL, file, cols = 1, layout = NULL) {
    library(grid)
    
    # Make a list from the ... arguments and plotlist
    plots <- c(list(...), plotlist)
    
    numPlots = length(plots)
    
    # If layout is NULL, then use 'cols' to determine layout
    if (is.null(layout)) {
        # Make the panel ncol: Number of columns of plots nrow: Number of rows
        # needed, calculated from # of cols
        layout <- matrix(seq(1, cols * ceiling(numPlots/cols)), ncol = cols, 
            nrow = ceiling(numPlots/cols))
    }
    
    if (numPlots == 1) {
        print(plots[[1]])
        
    } else {
        # Set up the page
        grid.newpage()
        pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
        
        # Make each plot, in the correct location
        for (i in 1:numPlots) {
            # Get the i,j matrix positions of the regions that contain this subplot
            matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
            
            print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row, layout.pos.col = matchidx$col))
        }
    }
}
# multiplot(p1, p2, p3, p4, cols=2) gridExtra包
# install.packages('gcookbook')
library(ggplot2)
library(gcookbook)
library(plyr)

4.1 简单折线图

折线图的x轴可以是离散型变量,也可以是连续型变量。如果x对应的是因子变量时,必须使用命令aes(group = 1)以确保这些数据点属于同一个分组,从而用一条折线连起来。

BOD
##   Time demand
## 1    1    8.3
## 2    2   10.3
## 3    3   19.0
## 4    4   16.0
## 5    5   15.6
## 6    7   19.8
p1 <- ggplot(BOD, aes(x = Time, y = demand)) + geom_line()

BOD1 <- BOD
BOD1$Time <- factor(BOD1$Time)
ggplot(BOD1, aes(x = Time, y = demand)) + geom_line()

p2 <- ggplot(BOD1, aes(x = Time, y = demand, group = 1)) + geom_line()  #因子水平无Time=6,所以x轴没有绘制相应的值
multiplot(p1, p2, cols = 2)

4.2 向折线图添加数据标记

使用geom_point()增加数据标记

ggplot(BOD, aes(x = Time, y = demand)) + geom_line() + geom_point()

4.3 绘制多重折线图

tg <- ddply(ToothGrowth, c("supp", "dose"), summarise, length = mean(len))
tg
##   supp dose length
## 1   OJ  0.5  13.23
## 2   OJ  1.0  22.70
## 3   OJ  2.0  26.06
## 4   VC  0.5   7.98
## 5   VC  1.0  16.77
## 6   VC  2.0  26.14
p1 <- ggplot(tg, aes(x = dose, y = length, colour = supp)) + geom_line()

# 当x轴为因子变量时,需要增加group的设置,否则无法绘出折线
p2 <- ggplot(tg, aes(x = factor(dose), y = length, colour = supp)) + geom_line()
p3 <- ggplot(tg, aes(x = factor(dose), y = length, colour = supp, group = supp)) + 
    geom_line()
multiplot(p1, p2, p3, cols = 3)

# 分组不正确时,就这些数据看做同一组数据,而用一个折线相连起来
ggplot(tg, aes(x = dose, y = length)) + geom_line()

4.4 修改线条样式

通过设置线型(linetype)、线宽(size)和颜色(colour)参数可以分别修改折线样式

ggplot(BOD, aes(x = Time, y = demand, colour = supp)) + geom_line(linetype = "dashed", 
    size = 1, colour = "blue")

ggplot(tg, aes(x = dose, y = length, colour = supp)) + geom_line() + scale_colour_brewer(palette = "Set1")

4.5 修改数据标记的样式

ggplot(BOD, aes(x = Time, y = demand)) + geom_line() + geom_point(size = 4, 
    shape = 21, colour = "black", fill = "pink")

4.6 绘制面积图

使用geom_area()即可绘制面积图,默认的填充色是黑灰色、没有边框,可通过设定fill和colour来修改填充色和边框,alpha可设置填充色的透明度

# 数据集sunspot.year是一个时间序列数据,需处理成数据框的格式
str(sunspot.year)
##  Time-Series [1:289] from 1700 to 1988: 5 11 16 23 36 58 29 20 10 8 ...
sunspotyear <- data.frame(Year = as.numeric(time(sunspot.year)), Sunspots = as.numeric(sunspot.year))
head(sunspotyear)
##   Year Sunspots
## 1 1700        5
## 2 1701       11
## 3 1702       16
## 4 1703       23
## 5 1704       36
## 6 1705       58
# 默认图形
p1 <- ggplot(sunspotyear, aes(x = Year, y = Sunspots)) + geom_area()

# 修改填充色,及透明度和边框颜色
p2 <- ggplot(sunspotyear, aes(x = Year, y = Sunspots)) + geom_area(fill = "blue", 
    colour = "black", alpha = 0.2)

# 去除起点和终点的垂直线和底部的横线,使用geom_line()增加一条折线即可
p3 <- ggplot(sunspotyear, aes(x = Year, y = Sunspots)) + geom_area(fill = "blue", 
    alpha = 0.2) + geom_line(colour = "darkred")
multiplot(p1, p2, p3, cols = 1)

4.7 绘制堆积面积图

使用geom_area(),同时将一个分类变量映射给填充色即可

p1 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) + geom_area()
p2 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) + geom_area(colour = "black", 
    size = 0.2, alpha = 0.4) + scale_fill_brewer(palette = "Blues", breaks = rev(levels(uspopage$AgeGroup)))
p3 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup, order = plyr::desc(AgeGroup))) + 
    geom_area(colour = "black", size = 0.2, alpha = 0.4) + scale_fill_brewer(palette = "Blues")
p4 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup, order = plyr::desc(AgeGroup))) + 
    geom_area(colour = NA, alpha = 0.4) + scale_fill_brewer(palette = "Blues") + 
    geom_line(position = "stack", size = 0.2)

ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) + geom_area(colour = NA, 
    alpha = 0.4) + scale_fill_brewer(palette = "Blues") + geom_line(position = "stack", 
    size = 0.2)

multiplot(p1, p2, p3, p4, cols = 2)

4.8 绘制百分比堆积面积图

方法一:首先计算各组对应的百分比,然后绘制堆积面积图

# 计算分组百分比
uspopage_prop <- ddply(uspopage, "Year", transform, Percent = Thousands/sum(Thousands) * 
    100)
head(uspopage_prop, 8)
##   Year AgeGroup Thousands   Percent
## 1 1900       <5      9181 12.065340
## 2 1900     5-14     16966 22.296107
## 3 1900    15-24     14951 19.648067
## 4 1900    25-34     12161 15.981549
## 5 1900    35-44      9273 12.186243
## 6 1900    45-54      6437  8.459274
## 7 1900    55-64      4026  5.290825
## 8 1900      >64      3099  4.072594
p1 <- ggplot(uspopage_prop, aes(x = Year, y = Percent, fill = AgeGroup)) + geom_area(colour = "black", 
    size = 0.2, alpha = 0.4) + scale_fill_brewer(palette = "Blues")

# 调整图例顺序
p2 <- ggplot(uspopage_prop, aes(x = Year, y = Percent, fill = AgeGroup)) + geom_area(colour = "black", 
    size = 0.2, alpha = 0.4) + scale_fill_brewer(palette = "Blues", breaks = rev(levels(uspopage$AgeGroup)))
multiplot(p1, p2, cols = 2)

方法二:直接设置geom_area(position = ‘fill’)

p1 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) + geom_area(colour = "black", 
    size = 0.2, alpha = 0.4, position = "stack")  # 简单堆积面积图
p2 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) + geom_area(colour = "black", 
    size = 0.2, alpha = 0.4, position = "fill")  # 百分比堆积面积图
p3 <- ggplot(uspopage, aes(x = Year, y = Thousands, fill = AgeGroup)) + geom_area(colour = "black", 
    size = 0.2, alpha = 0.4, position = "identity")  # 分类面积图
multiplot(p1, p2, p3, cols = 3)

4.9 添加置信域

使用geom_ribbon(),分别映射一个变量给ymin和ymax。

clim <- subset(climate, Source == "Berkeley", select = c("Year", "Anomaly10y", 
    "Unc10y"))
head(clim)
##   Year Anomaly10y Unc10y
## 1 1800     -0.435  0.505
## 2 1801     -0.453  0.493
## 3 1802     -0.460  0.486
## 4 1803     -0.493  0.489
## 5 1804     -0.536  0.483
## 6 1805     -0.541  0.475
p1 <- ggplot(clim, aes(x = Year, y = Anomaly10y)) + geom_ribbon(aes(ymin = Anomaly10y - 
    Unc10y, ymax = Anomaly10y + Unc10y), alpha = 0.2) + geom_line()
p2 <- ggplot(clim, aes(x = Year, y = Anomaly10y)) + geom_ribbon(aes(ymin = Anomaly10y - 
    Unc10y, ymax = Anomaly10y + Unc10y), alpha = 0.2) + geom_line(aes(y = Anomaly10y - 
    Unc10y), colour = "grey50", linetype = "dotted") + geom_line(aes(y = Anomaly10y + 
    Unc10y), colour = "grey50", linetype = "dotted") + geom_line()
multiplot(p1, p2, cols = 1)