数据准备
df <- read.table(file = "D:/Documents/R wd/df.csv", header = T, sep = ",") # 数据导入。
df # 查看数据。
## year nitrogen variety block v1 v2 v3 v4 v5
## 1 2020 N1 a 1 1.26 2.14 0.4 5.0 3.25
## 2 2020 N1 a 2 1.20 2.90 0.1 5.3 1.27
## 3 2020 N1 a 3 1.30 3.00 0.3 5.6 2.24
## 4 2020 N1 b 1 1.08 1.72 1.8 2.8 1.00
## 5 2020 N1 b 2 1.05 1.65 1.7 2.5 3.12
## 6 2020 N1 b 3 1.15 1.35 1.5 3.1 4.57
## 7 2020 N2 a 1 1.32 3.78 1.6 6.0 5.85
## 8 2020 N2 a 2 1.28 4.32 1.4 6.1 6.48
## 9 2020 N2 a 3 1.35 3.95 1.3 6.2 7.21
## 10 2020 N2 b 1 1.33 3.47 2.8 4.1 6.56
## 11 2020 N2 b 2 1.28 2.72 2.4 4.3 8.43
## 12 2020 N2 b 3 1.30 3.90 2.2 4.5 7.55
## 13 2021 N1 a 1 1.19 3.61 0.8 6.0 3.11
## 14 2021 N1 a 2 1.21 3.29 0.5 5.7 2.54
## 15 2021 N1 a 3 1.24 3.26 0.7 5.6 1.28
## 16 2021 N1 b 1 1.09 2.71 1.8 4.0 3.24
## 17 2021 N1 b 2 1.28 2.32 1.6 4.2 1.27
## 18 2021 N1 b 3 1.35 1.95 1.3 4.3 1.15
## 19 2021 N2 a 1 1.45 4.35 1.8 7.2 5.74
## 20 2021 N2 a 2 1.40 3.80 1.2 7.0 6.85
## 21 2021 N2 a 3 1.37 4.23 1.6 6.8 7.42
## 22 2021 N2 b 1 1.28 2.72 2.4 5.1 8.20
## 23 2021 N2 b 2 1.15 3.35 2.5 5.5 5.70
## 24 2021 N2 b 3 1.24 3.46 2.7 4.9 6.00
df$nitrogen <- as.factor(df$nitrogen) # 转化因子。
df$variety <- as.factor(df$variety) # 转化因子。
第16章 高级图形进阶
除了基础图形,grid、lattice和ggplot2软件包也提供了图形系统,它们克服了R基础图形系统的低效性,大大扩展了R的绘图能力。
grid图形系统可以很容易控制图形基础单元,给予编程者创作图形极大的灵活性。lattice包通过一维、二维或三维条件绘图,即所谓的栅栏(trellis)图形来对多元变量关系进行直观展示。ggplot2包则基于一种全面的图形“语法”,提供了一种全新的图形创建方法。
16.1 R中的四种图形系统
如前所述,R中有四种主要的图形系统。其中基础图形系统由Ross Ihaka编写,每个R都默认安装,之前几章中的大部分图形都是依赖于基础图形函数创建的。
grid图形系统由Paul Murrell(2006)编写,可通过grid包安装执行。grid图形提供了一种比标准图形系统更低水平的方法。用户可以在图形设备上随意创建矩形区域,在该区域定义坐标系统,然后使用一系列丰富的绘图基础单元来控制图形元素的摆放和外观。
grid图形的灵活性对于软件开发者是非常有价值的,但是grid包没有提供生成统计图形以及完整绘图的函数。因此,数据分析师很少直接采用grid包来分析数据。
lattice包由Deepayan Sarkar(2008)编写,基于grid包,lattice包对多元数据的可视化功能已经远超Cleveland的原始方法,它为R提供了一种全面的、创建统计图形的备选系统。
ggplot2包由Hadley Wickham(2009a)编写,它提供了一种基于Wilkinson(2005)所描述的图形语法的图形系统,Wickham(2009b)还对该语法进行了扩展。ggplot2包的目标是提供一个全面的、基于语法的、连贯一致的图形生成系统,允许用户创建新颖的、有创新性的数据可视化图形。
16.2 lattice包
library(lattice) # 调用lattice包。
histogram(~ height | voice.part,data = singer, main = "Distribution of Heights by Voice Pitch", xlab = "Height(inches)") # 对数据集singer中每个声部绘制直方图分布。
height是因变量,voice.part被称作条件变量(conditioning variable)。在栅栏图形中,单个面板要依据条件变量的各个水平来创建。如果指定了多个条件变量,那么一个面板将按照各个因子水平的组合来创建。然后面板将被排成一个阵列以进行比较。每个面板在一个区域都会有一个标签,这里的区域称作条带区域(strip)。
lattice包提供了丰富的函数,可生成单变量图形(点图、核密度图、直方图、柱状图和箱线图)、双变量图形(散点图、带状图和平行箱线图)和多变量图形(三维图和散点图矩阵)。
各种高级绘图函数都服从以下格式:
graph_function(formula, data, options)
graph_function是表16-2的第二栏列出的某个函数。
formula指定要展示的变量和条件变量。
data指定一个数据框。
options是逗号分隔参数,用来修改图形的内容、摆放方式和标注。表16-3列出了一些常见的选项。
设小写字母代表数值型变量,大写字母代表类别型变量(因子)。绘图函数表达式形式通常为:
y ~ x | A * B
在竖线左边的变量称为主要(primary)变量,右边的变量称为条件(conditioning)变量。
主要变量将变量映射到每个面板的坐标轴上,此处,y ~ x表示变量分别映射到纵轴和横轴上。
对于单变量绘图,用~ x代替y ~ x即可;对于三维图形,用z ~ xy代替y ~ x,而对于多变量绘图(散点图矩阵或平行坐标图)用一个数据框代替y ~ x即可。注意,条件变量总是可以自行挑选的。
根据上述的逻辑,~ x | A即展示因子A各个水平下数值型变量x的分布情况;y ~ x | AB即展示因子A和B各个水平组合下数值型变量x和y间的关系。而A ~ x则表示类别型变量A在纵轴上,数值型变量x在横轴上进行展示。~ x表示仅展示数值型变量x。
library(lattice) # 调用lattice包。
contourplot(volcano) # 等高线图示例。
levelplot(v5~v1*v3,data = df) # 三维水平图示例。
cloud(v3~v1*v2,data = df) # 三维散点图。
cloud(v3 ~ v1 * v2 | nitrogen, data = df, main = "3D Scatter Plots by Nitrogen") # 三维散点图。z为v3,x为v1,y为v2。以nitrogen分组。
wireframe(volcano) # 三维线框图示例。
barchart(v3 ~ nitrogen, data = df) # 条形图示例。
barchart(v3 ~ year|nitrogen, data = df) # 条形图分组示例。
bwplot(df$v1) # 箱线图示例。
bwplot(year ~ v1, data = df, main = "Box Plots by Nitrogen ", xlab = "v1", ylab = "year") # 以nitrogen为分组的v3箱线图。
dotplot(~v3, data = df) # 点图示例。
dotplot(v3 ~ v1 | year, data = df, main = "Dot Plots by Number of Nitrogen and Year", xlab = "v1") # year分组的v3和v1的散点图。
histogram(~v3, data = df) # 直方图示例。
histogram(~v3|nitrogen, data = df) # 分组直方图示例。
densityplot(~ v1, data = df, main = "Density Plot", xlab = "v1") # df数据集v1密度图。
densityplot(~ v1 | nitrogen, data = df, main = "Density Plot by Nitrogen", xlab = "v1") # 以nitrogen为分组的v1变量密度图。
parallelplot(df[5:8]) # 平行坐标图示例。
xyplot(v3 ~ v1, data = df) # 散点图示例。
xyplot(v3 ~ v1 | nitrogen * year, data = df, main = "Scatter Plots by Nitrogen and Years", xlab = "v1", ylab = "v3") # year和nitrogen分组的v3和v1的散点图。
splom(df[5:8], data= df, main = "Scatter Plot Matrix for mtcars Data") # 散点图矩阵。
stripplot(v3 ~ nitrogen, data = df) # 带状图示例。
16.2.1 条件变量
通常,条件变量是因子。但是,如果想以连续型变量为条件,该怎么办呢?一种方法是利用R的cut()函数将连续型变量转换为离散变量。另外,lattice包提供了一些将连续型变量转化为瓦块(shingle)数据结构的函数。特别地,连续型变量会被分割到一系列(可能)重叠的数值范围中。
myshingle<-equal.count(x,number=#,overlap=proportion)
x为连续形向量,number为需要分为#个瓦块,overlap为重叠度proportion,可以为0。
displacement <- equal.count(df$v1, number=3,overlap=0) # 定义瓦块变量。
xyplot(v5 ~ v3 |displacement, data = df) # 绘制散点图。
图解:深色表示每个面板中条件变量的取值范围。
16.2.2 面板函数
mypanel <- function(x,y){
panel.xyplot(x,y,pch = 15)
panel.rug(x,y)
panel.grid(h=-1,v=-1)
panel.lmline(x,y,col="red",lwd=1,lty=2)
} # 自定义面板函数。
xyplot(v5 ~ v1|displacement, data = df, panel = mypanel) # 使用自定义面板函数绘制散点图。
panel.smoother <- function(x,y){
panel.grid(h=-1,v=-1)
panel.xyplot(x,y)
panel.loess(x,y)
panel.abline(h=mean(y),lwd = 2,lty = 2,col="blue")
} # 自定义面板函数,定义了拟合线形式和参考线。
xyplot(v5 ~ v3 |nitrogen, data = df, panel = panel.smoother) # 使用自定义拟合线面板函数绘制散点图。
16.2.3 分组变量
当一个lattice图形表达式含有条件变量时,将会生成在该变量各个水平下的面板。若你想将结果叠加到一起,则可以将变量设定为分组变量(grouping variable)。
group =选项默认将分组变量各个水平下的图形叠加到一起。
densityplot(~ v5 | nitrogen, data = df) # 密度图。
densityplot(~ v5,data = df,groups = nitrogen) # 分组密度图。
densityplot(~ v5,data = df,groups = nitrogen,auto.key = TRUE) # 分组密度图带图例。
分组变量和条件变量同时包含在一幅图形中的例子。数据集使用的是R基础安装中的CO2数据框,它描述的是一个对稗草耐寒度的研究。
数据结构:数据包含了12个植物(Plant)在七种二氧化碳浓度环境(conc)中的二氧化碳吸收率(uptake)。六个植物来自加拿大的魁北克省,另外六个来自美国的密西西比州。其中每组的三个植物处于严寒环境,另外三个处于非严寒环境。本例中,Plant是分组变量,而Type(魁北克省/密西西比州)和Treatment(严寒/非严寒)是条件变量。
CO2 # 查看数据集。
## Plant Type Treatment conc uptake
## 1 Qn1 Quebec nonchilled 95 16.0
## 2 Qn1 Quebec nonchilled 175 30.4
## 3 Qn1 Quebec nonchilled 250 34.8
## 4 Qn1 Quebec nonchilled 350 37.2
## 5 Qn1 Quebec nonchilled 500 35.3
## 6 Qn1 Quebec nonchilled 675 39.2
## 7 Qn1 Quebec nonchilled 1000 39.7
## 8 Qn2 Quebec nonchilled 95 13.6
## 9 Qn2 Quebec nonchilled 175 27.3
## 10 Qn2 Quebec nonchilled 250 37.1
## 11 Qn2 Quebec nonchilled 350 41.8
## 12 Qn2 Quebec nonchilled 500 40.6
## 13 Qn2 Quebec nonchilled 675 41.4
## 14 Qn2 Quebec nonchilled 1000 44.3
## 15 Qn3 Quebec nonchilled 95 16.2
## 16 Qn3 Quebec nonchilled 175 32.4
## 17 Qn3 Quebec nonchilled 250 40.3
## 18 Qn3 Quebec nonchilled 350 42.1
## 19 Qn3 Quebec nonchilled 500 42.9
## 20 Qn3 Quebec nonchilled 675 43.9
## 21 Qn3 Quebec nonchilled 1000 45.5
## 22 Qc1 Quebec chilled 95 14.2
## 23 Qc1 Quebec chilled 175 24.1
## 24 Qc1 Quebec chilled 250 30.3
## 25 Qc1 Quebec chilled 350 34.6
## 26 Qc1 Quebec chilled 500 32.5
## 27 Qc1 Quebec chilled 675 35.4
## 28 Qc1 Quebec chilled 1000 38.7
## 29 Qc2 Quebec chilled 95 9.3
## 30 Qc2 Quebec chilled 175 27.3
## 31 Qc2 Quebec chilled 250 35.0
## 32 Qc2 Quebec chilled 350 38.8
## 33 Qc2 Quebec chilled 500 38.6
## 34 Qc2 Quebec chilled 675 37.5
## 35 Qc2 Quebec chilled 1000 42.4
## 36 Qc3 Quebec chilled 95 15.1
## 37 Qc3 Quebec chilled 175 21.0
## 38 Qc3 Quebec chilled 250 38.1
## 39 Qc3 Quebec chilled 350 34.0
## 40 Qc3 Quebec chilled 500 38.9
## 41 Qc3 Quebec chilled 675 39.6
## 42 Qc3 Quebec chilled 1000 41.4
## 43 Mn1 Mississippi nonchilled 95 10.6
## 44 Mn1 Mississippi nonchilled 175 19.2
## 45 Mn1 Mississippi nonchilled 250 26.2
## 46 Mn1 Mississippi nonchilled 350 30.0
## 47 Mn1 Mississippi nonchilled 500 30.9
## 48 Mn1 Mississippi nonchilled 675 32.4
## 49 Mn1 Mississippi nonchilled 1000 35.5
## 50 Mn2 Mississippi nonchilled 95 12.0
## 51 Mn2 Mississippi nonchilled 175 22.0
## 52 Mn2 Mississippi nonchilled 250 30.6
## 53 Mn2 Mississippi nonchilled 350 31.8
## 54 Mn2 Mississippi nonchilled 500 32.4
## 55 Mn2 Mississippi nonchilled 675 31.1
## 56 Mn2 Mississippi nonchilled 1000 31.5
## 57 Mn3 Mississippi nonchilled 95 11.3
## 58 Mn3 Mississippi nonchilled 175 19.4
## 59 Mn3 Mississippi nonchilled 250 25.8
## 60 Mn3 Mississippi nonchilled 350 27.9
## 61 Mn3 Mississippi nonchilled 500 28.5
## 62 Mn3 Mississippi nonchilled 675 28.1
## 63 Mn3 Mississippi nonchilled 1000 27.8
## 64 Mc1 Mississippi chilled 95 10.5
## 65 Mc1 Mississippi chilled 175 14.9
## 66 Mc1 Mississippi chilled 250 18.1
## 67 Mc1 Mississippi chilled 350 18.9
## 68 Mc1 Mississippi chilled 500 19.5
## 69 Mc1 Mississippi chilled 675 22.2
## 70 Mc1 Mississippi chilled 1000 21.9
## 71 Mc2 Mississippi chilled 95 7.7
## 72 Mc2 Mississippi chilled 175 11.4
## 73 Mc2 Mississippi chilled 250 12.3
## 74 Mc2 Mississippi chilled 350 13.0
## 75 Mc2 Mississippi chilled 500 12.5
## 76 Mc2 Mississippi chilled 675 13.7
## 77 Mc2 Mississippi chilled 1000 14.4
## 78 Mc3 Mississippi chilled 95 10.6
## 79 Mc3 Mississippi chilled 175 18.0
## 80 Mc3 Mississippi chilled 250 17.9
## 81 Mc3 Mississippi chilled 350 17.9
## 82 Mc3 Mississippi chilled 500 17.9
## 83 Mc3 Mississippi chilled 675 18.9
## 84 Mc3 Mississippi chilled 1000 19.9
colors <- "darkgreen" # 自定义颜色赋值colors。
symbols <- c(1:12) # 自定义图标识。
linetype <- c(1:3) # 自定义线型。
key.species <- list(title = "Plant", space = "right", text = list(levels(CO2$Plant)), points = list(pch = symbols, col = colors)) # 图例参数设置,title定义标题,space指定图例位置,text指定文本内容,points指定点的参数(颜色和形状)。
xyplot(uptake ~ conc | Type * Treatment, data = CO2, group = Plant, type = "o",
pch = symbols, col = colors, lty = linetype,
main = "Carbon Dioxide Uptake\nin Grass Plants",
ylab = expression(paste("Uptake ", bgroup("(", italic(frac("umol", "m"^2)), ")"))),
xlab = expression(paste("Concentration ", bgroup("(", italic(frac(mL, L)), ")"))),
sub = "Grass Species: Echinochloa crus-galli",
key = key.species) # 散点图绘制,自变量uptake,因变量conc,条件变量type和treatment,group指定分组(分组依据plant),type指定图形类型(o为点线图);pch指定符号(选择自定义的symbols);col指定颜色(选择自定义的colors);lty指定线型(选择自定义的linetype);main指定主标题(\n将会使标题分成两行);ylab和xlab指定y和x坐标轴标题(expression()函数将在坐标轴标签上添加数学符号,paste函数用于符号组合,italic用于指定输出为希腊字母,frac是数学符号分号;);sub指定副标题,key指定图例(选择自定义的key.species。)
16.2.4 图形参数
在lattice图形中,lattice函数默认的图形参数包含在一个很大的列表对象中,你可通过trellis.par.get()函数来获取,并用trellis.par.set()函数来修改。show.settings()函数可展示当前的图形参数设置情况。
show.settings() # 显示当前图形参数设置情况。
mysettings <- trellis.par.get() # 获取参数,赋值给mysettings。
mysettings$superpose.symbol # 查看默认参数。
## $alpha
## [1] 1 1 1 1 1 1 1
##
## $cex
## [1] 0.8 0.8 0.8 0.8 0.8 0.8 0.8
##
## $col
## [1] "#0080ff" "#ff00ff" "darkgreen" "#ff0000" "orange" "#00ff00"
## [7] "brown"
##
## $fill
## [1] "#CCFFFF" "#FFCCFF" "#CCFFCC" "#FFE5CC" "#CCE6FF" "#FFFFCC" "#FFCCCC"
##
## $font
## [1] 1 1 1 1 1 1 1
##
## $pch
## [1] 1 1 1 1 1 1 1
mysettings$superpose.symbol$pch <- c(1:10) # 定义点图形符号参数为10个水平,图形符号被定义后将会被循环使用。
trellis.par.get(mysettings) # 获取修改后的参数。
show.settings() # 显示修改后图形参数设置情况。
16.2.5 页面摆放
最简单的方法便是先将lattice图形存储到对象中,然后利用plot()函数中的split =或position =选项来进行控制。
split选项将页面分割为一个指定行数和列数的矩阵,然后将图形放置到该矩阵中。split选项的格式为:
split=c(placement column,placement row,total number of columns,total number of rows)
split组图
split=c(列位置号码,行位置号码,列数,行数)。
library(lattice) # 调用lattice包。
graph1 <- histogram(~height | voice.part, data = singer,
main = "Heights of Choral Singers by Voice Part") # 绘制graph1。
graph2 <- densityplot(~height, data = singer, group = voice.part,
plot.points = FALSE, auto.key = list(columns = 4)) # 绘制graph2。
plot(graph1, split = c(1, 1, 1, 2)) # graph1排布。
plot(graph2, split = c(1, 2, 1, 2), newpage = FALSE) # graph2排布。
position组图
position = c(xmin, ymin, xmax, ymax),该页面的x-y坐标系统是矩形,x轴和y轴的维度范围都是从0到1,原点(0,0)在图形左下角。
graph1 <- histogram(~height | voice.part, data = singer,
main = "Heights of Choral Singers by Voice Part") # graph1
graph2 <- densityplot(~height, data = singer, group = voice.part, plot.points = FALSE, auto.key = list(columns = 4)) # graph2
plot(graph1, position = c(0, 0.4, 1, 1)) # graph1排布。
plot(graph2, position = c(0, 0, 1, 0.4), newpage = FALSE) # graph2排布。
在lattice图形中你还可以改变面板的顺序。高级绘图函数的index.cond =选项可以设定条件变量水平的顺序。
levels(df$nitrogen) # 查看因子水平。
## [1] "N1" "N2"
xyplot(v3 ~ v1|nitrogen, data = df, index.cond = list(c(2,1))) # 改变因子顺序作图。
16.3 ggplot2包
ggplot2包提供了一个基于全面而连贯的语法的绘图系统。ggplot2中最简单的绘图方式是利用qplot()函数,即快速绘图函数。
qplot(x,y,data=,color=,shape=,size=,alpha=,geom=,method=,formula=,facets=,xlim=,ylim=,xlab=,ylab=,main=,sub=)
library(ggplot2) # 调用ggplot2包。
qplot(nitrogen, v5, data = df, geom = c("boxplot", "jitter"), fill = nitrogen, main = "Box plot with superimposed data points", xlab = "v1", ylab = "v5") # 快速出图nitrogen水平下v5箱图带点图。
线性拟合的例子
library(ggplot2) # 调用ggplot2包。
transmission <- factor(mtcars$am, levels = c(0, 1),
labels = c("Automatic", "Manual")) # 因子设置。
qplot(wt, mpg, data = mtcars,
color = transmission, shape = transmission,
geom = c("point", "smooth"),
method = "lm", formula = y ~ x,
xlab = "Weight", ylab = "Miles Per Gallon",
main = "Regression Example") # 颜色和符号形状区分自动挡和手动挡汽车。
自己的数据试一下
qplot(v1, v5, data = df, color = nitrogen, shape = nitrogen, geom = c("point", "smooth"), method = "lm", formula = y ~ x, xlab = "v1", ylab = "v5", main = "Regression between v1 and v5") # qplot绘制以nitrogen分组的v1和v5之间的线性拟合。
上图还可以用以下代码实现。
ggplot(df, aes(x = v1, y = v5, colour=nitrogen, shape = nitrogen)) + geom_point()+ geom_smooth(method = "lm") + labs(title = "Regression between v1 and v5", x = "v1", y = "v5") # 使用ggplot绘制上图。
分面的例子
library(ggplot2) # 调用ggplot包。
qplot(v1, v5, data = df, facets = nitrogen ~ year, size = v1) # 分面散点图。nitrogen定义了行分面,year定义了列分面。数据点的大小由v1定义。
同样地,以下代码可以实现上图。
ggplot(df, aes(x = v1, y = v5, size = v1)) + geom_point() + facet_grid(nitrogen ~ year) # 用ggplot绘制。
library(ggplot2) # 调用ggplot2包。
data(singer, package = "lattice") # 调用lattice包中的singer数据集。
qplot(height, data = singer, geom = c("density"), facets = voice.part ~ ., fill = voice.part) # qplot绘制密度图。
ggplot(singer,aes(height, fill = voice.part)) + geom_density() + facet_grid(voice.part ~.) # ggplot绘制上图。
《R语言实战》只是简单的展示了ggplot2绘图,ggplot2绘图系统很强大,由ggplot2衍生的包也很多,极大的丰富了其绘图功能,均需系统学习。
16.4 交互式图形
16.4.1 与图形交互:鉴别点
R基础安装中一个可对散点图中的点进行鉴别和标注的函数:identify()。利用该函数,你可用鼠标对散点图中所选择的点标注行数或者行名称,直到你选择了Stop或者右击图形识别工作才会停止。
16.4.2 playwith
playwith包提供了一个GTK+图形用户界面(GUI),使得用户可以编辑R图形并与其交互。
playwith()函数允许用户识别和标注点、查看一个观测所有的变量值、缩放和旋转图形、添加标注(文本、箭头、线条、矩形、标题和标签)、修改视觉元素(颜色、文本大小等)、应用先前存储的图形风格,以及以多种格式输出图形结果。
16.4.3 latticist
除了拥有playwith的函数功能(识别点、标注、缩放、旋转和风格化),用户还能通过下拉菜单和按钮直接创建lattice图形。
16.4.4 iplots包的交互图形
该包提供了交互式马赛克图、柱状图、箱线图、平行坐标图、散点图和直方图,以及颜色刷,并可将它们结合在一起绘制。这意味着你可通过鼠标对观测点进行选择和识别,并且对其中一幅图形的观测点突出显示时,其他被打开的图形将会自动突出显示相同的观测点。另外,你还可通过鼠标来收集图形对象(诸如点、条、线)和箱线图的信息。
iplots包中的函数可用来探索变量分布和交互选择的观测子集中的变量关系。
16.4.5 rggobi
GGobi有许多吸引眼球的优点,包括:交互式散点图、柱状图、平行坐标图、时间序列图、散点图矩阵和三维旋转的综合使用;窗口刷和点识别;多变量变换方法;复杂的探索平台,如导向动画的和手动的1维及2维图形。令人振奋的是,rggobi软件包为GGobi和R提供了一个无缝接口。
16.5 小结
参考资料:
- 《R语言实战》(中文版),人民邮电出版社,2013.