本章内容
图形的创建和保存
自定义符号、线条、颜色和坐标轴
标注文本和标题
控制图形维度
组合多个图形
3.1 使用图形
attach(mtcars)
plot(wt, mpg)
abline(lm(mpg~wt)) # 向图形添加了一条最优拟合曲线
title("Regression of MPG on Weight") #添加了标题
detach(mtcars)
- 保存图形:要通过代码保存图形,将绘图语句夹在开启目标 图形设备的语句和关闭目标图形设备的语句之间即可。例如,以下代码会将图形保存到当前工作 目录中名为mygraph.pdf的PDF文件中:
- 除了pdf(),还可以使用函数win.metafile()、png()、jpeg()、bmp()、tiff()、xfig() 和postscript()将图形保存为其他格式。
pdf("mygraph.pdf")
attach(mtcars)
plot(wt, mpg)
abline(lm(mpg~wt))
title("Regression of MPG on Weight")
detach(mtcars)
dev.off()
- 创建多个图形:
- 通过执行如plot()、hist()(绘制直方图)或boxplot()这样的高级绘图命令来创建一幅 新图形时,通常会覆盖掉先前的图形。如何才能创建多个图形并随时查看每一个呢?
- 方法1:创建下一个图形之前打开一个新的图形窗口
dev.new()
statements to create graph 1
dev.new() # 创建下一个图形之前打开一个新的图形窗口
statements to create a graph 2
etc.
- 方法2:通过图形用户界面来查看多个图形
在Windows上,这个过程分为两 步。在打开第一个图形窗口以后,勾选“历史”(History)→“记录”(Recording)。然后使用菜 单中的“上一个”(Previous)和“下一个”(Next)来逐个查看已经绘制的图形。
- 方法3:最后一种方法,你可以使用函数dev.new()、dev.next()、dev.prev()、dev.set()和 dev.off()同时打开多个图形窗口,并选择将哪个输出发送到哪个窗口中。
形成矩阵:
a<-c(20,30,40,45,60,16,20,27,40,60,15,18,25,31,40)
cnames<-c("剂量","对药物A的响应","对药物B的响应")
mymatrix<-matrix(a,nrow=5,ncol=3,byrow=FALSE)
colnames(mymatrix)<-cnames
matrix
3.2 简单图像制作
dose <- c(20, 30, 40, 45, 60)
drugA <- c(16, 20, 27, 40, 60)
drugB <- c(15, 18, 25, 31, 40)
plot(dose, drugA, type="b")
将x置于横轴,将y置于纵轴,绘制点集(x, y),然后使用线段 将其连接。选项type="b"表示同时绘制点和线。
- help(plot)可以查看其他选项
3.3 图形参数
- 方法1:函数par():以这种方式设定的参数值除非被再次修改, 否则将在会话结束前一直有效。
- par(optionname=value, optionname=name,...)。
- 不加参数地执行par()将生成一个含有当前图形参数设置的列表。
- 添加参数no.readonly=TRUE可以生成一个可以修改的当前图形参数列表。
- 例子:
- opar <- par(no.readonly=TRUE)
- par(lty=2, pch=17) :默认的线条类型修改为虚线(lty=2),将默认的点符号改为了实心三角(pch=17);也可以拆开使用
- plot(dose, drugA, type="b")
- par(opar)
- 方法2:为高级绘图函数直接提供optionname=value的键值对
- 指定的选项仅对这幅图形本身有效。
- plot(dose, drugA, type="b", lty=2, pch=17)
3.3.1 符号与线条
指定符号
指定线条
结合上述
plot(dose, drugA, type="b", lty=3, lwd=3, pch=15, cex=2)
- type=b:同时绘制点线
- ity=3:点点
- lwd=3:宽度
- pch=15:正方形小点
- cex=2:放大两倍
3.3.2 颜色
- hsv:基于色相- 饱和度-亮度值来生成颜色
- 函数colors()可以返回所有可用颜色的名称
- Earl F. Glynn为R中的色彩创建了一个优秀的 在线图表,参见http://research.stowers-institute.org/efg/R/Color/Chart
- R中也有多种用于创建连续 型颜色向量的函数,包括rainbow()、heat.colors()、terrain.colors()、topo.colors() 以及cm.colors()。举例来说,rainbow(10)可以生成10种连续的“彩虹型”颜色
- 创建吸引人的颜色配对
- 使用函数brewer.pal(n, name) 来创建一个颜色值的向量。
举个例子
library(RColorBrewer)
n <- 7
mycolors <- brewer.pal(n, "Set1")
barplot(rep(1,n), col=mycolors)
从Set1调色板中抽取了7种用十六进制表示的颜色并返回一个向量。
- 若要得到所有可选调色板的 列表,输入brewer.pal.info;或者输入display.brewer.all()从而在一个显示输出中产生 每个调色板的图形。
用灰色:多阶灰度色可使用基础安装所自带的gray()函数生成。这时要通过一个元素值为0和 1之间的向量来指定各颜色的灰度。gray(0:10/10)将生成10阶灰度色。
n <- 10
mycolors <- rainbow(n)
pie(rep(1, n), labels=mycolors, col=mycolors)
mygrays <- gray(0:n/n)
pie(rep(1, n), labels=mygrays, col=mygrays)
3.3.3 文本属性
par(font.lab=3, cex.lab=1.5, font.main=4, cex.main=2)
之后创建的所有图形都将拥有斜体、1.5倍于默认文本大小的坐标轴标签(名称),以及粗斜体、 2倍于默认文本大小的标题。
3.3.4 图形尺寸与边界尺寸
par(pin=c(4,3), mai=c(1,.5, 1, .2))
可生成一幅4英寸宽、3英寸高、上下边界为1英寸、左边界为0.5英寸、右边界为0.2英寸的图形。 关于边界参数的完整指南,
http://research.stowers-institute.org/efg/R/Graphics/Basics/mar-oma/
3.3的综合例子
dose <- c(20, 30, 40, 45, 60)
drugA <- c(16, 20, 27, 40, 60)
drugB <- c(15, 18, 25, 31, 40)
opar <-par(no.readonly = TRUE)
par(pin=c(2,3)) # 尺寸是宽2英寸,长3英寸
par(lwd=2,cex=1.5) # 线条宽度是2,符号大小1.5
par(cex.axis=.75,font.axis=3) # 坐标轴刻度文字缩放倍数为0.75,文字样式为3
plot(dose, drugA, type="b", pch=19, lty=2, col="red")# 画图,点线结合,点是原点,线条是虚线,颜色是红色
plot(dose, drugB, type="b", pch=23, lty=6, col="blue", bg="green") # 填充是绿的
par(opar)
# 注意:通过par()设定的参数对两幅图都有效,而在plot()函数中指定的参数仅对那个特定图形有效。
3.4 添加文本、自定义坐标轴和图例
注意:再次提醒,并非所有函数都支持这些选项。请参考相应函数的帮助以了解其可以接受哪些选 项。从更精细的控制和模块化的角度考虑,你可以使用本节余下部分描述的函数来控制标题、坐 标轴、图例和文本标注的外观
某些高级绘图函数已经包含了默认的标题和标签。你可以通过在plot()语句或单独的 par()语句中添加ann=FALSE来移除它们。
3.4.1标题:title()
title(main="main title", sub="subtitle", xlab="x-axis label", ylab="y-axis label")
函数title()中亦可指定其他图形参数(如文本大小、字体、旋转角度和颜色)。
#以下代码将生成红色的标题和蓝色的副标题,以及比默认大小小25%的绿色x轴、y轴标签:
title(main="My Title", col.main="red",
sub="My Subtitle", col.sub="blue",
xlab="My X label", ylab="My Y label",
col.lab="green", cex.lab=0.75)
3.4.2 坐标轴:axis()
axis(side, at=, labels=, pos=, lty=, col=, las=, tck=, ...)
例子
x <- c(1:10)
y <- x
z <- 10/x
opar <- par(no.readonly=TRUE)
par(mar=c(5, 4, 4, 8) + 0.1)
plot(x, y, type="b",
pch=21, col="red",
yaxt="n", lty=3, ann=FALSE)
lines(x, z, type="b", pch=22, col="blue", lty=2)
axis(2, at=x, labels=x, col.axis="red", las=2)
axis(4, at=z, labels=round(z, digits=2),
col.axis="blue", las=2, cex.axis=0.7, tck=-.01)
mtext("y=1/x", side=4, line=3, cex.lab=1, las=2, col="blue")
title("An Example of Creative Axes",
xlab="X values",
ylab="Y=X")
par(opar)
- 使用lines()语句,你可以为一幅现有图形添加新的图形元 素。
- 函数mtext() 用于在图形的边界添加文本。
次要刻度线
注意,我们最近创建的图形都只拥有主刻度线,却没有次要刻度线。
要创建次要刻度线, 你需要使用Hmisc包中的minor.tick()函数。
如果你尚未安装Hmisc包,请先安装它(参考 1.4.2节)。
你可以使用代码:
library(Hmisc)
minor.tick(nx=n, ny=n, tick.ratio=n) 来添加次要刻度线。
其中nx和ny分别指定了X轴和Y轴每两条主刻度线之间通过次要刻度线划分得到的区间个数。tick.ratio表示次要刻度线相对于主刻度线的大小比例。
当前的主刻度 线长度可以使用par("tck")获取。
举例来说,下列语句:将在X轴的每两条主刻度线之间添加1 条次要刻度线,并在Y轴的每两条主刻度线之间添加2条次要刻度线:次要刻度线的长度将是主刻度线的一半。
minor.tick(nx=2, ny=3, tick.ratio=0.5)
3.4.4节中给出了添加次要刻度线的一个例子(代码清 单3-3和图3-10)。
3.4.3 参考线:abline()
abline(h=yvalues, v=xvalues)
函数abline()中也可以指定其他图形参数(如线条类型、颜色和宽度)。
abline(h=c(1,5,7)) #在y为1、5、7的位置添加了水平实线
abline(v=seq(1, 10, 2), lty=2, col="blue") #则在x为1、3、5、7、9的位置添加了垂直的蓝色虚线
3.4.4 图例:legend()来添加图例
legend(location, title, legend, ...)
其他常用的图例选项包括:
用于指定盒子样式的bty、
指定背景色的bg、
指定大小的cex,
以 及指定文本颜色的text.col。
指定horiz=TRUE将会水平放置图例,而不是垂直放置。
help(legend)
例子
dose <- c(20, 30, 40, 45, 60)
drugA <- c(16, 20, 27, 40, 60)
drugB <- c(15, 18, 25, 31, 40)
opar <- par(no.readonly=TRUE)
par(lwd=2, cex=1.5, font.lab=2)
plot(dose, drugA, type="b",
pch=15, lty=1, col="red", ylim=c(0, 60),
main="Drug A vs. Drug B",
xlab="Drug Dosage", ylab="Drug Response")
lines(dose, drugB, type="b",
pch=17, lty=2, col="blue") # 为一幅现有图形添加新的图形元 素
abline(h=c(30), lwd=1.5, lty=2, col="gray") # 参考线
library(Hmisc) #添加次要刻度线
minor.tick(nx=3, ny=3, tick.ratio=0.5)
legend("topleft", inset=.05, title="Drug Type", c("A","B")
lty=c(1, 2), pch=c(15, 17), col=c("red", "blue")) #添加图例
par(opar)
3.4.5 文本标注:以通过函数text()和mtext()将文本添加到图形上
- text()可向绘图区域内部添加 文本,
- 而mtext()则向图形的四个边界之一添加文本。
- 使用格式分别为:
- text(location, "text to place", pos, ...)
- mtext("text to place", side, line=n, ...)
- 其他常用的选项有cex、col和font(分别用来调整字号、颜色和字体样式)
- 除了用来添加文本标注以外,text()函数也通常用来标示图形中的点。我们只需指定一系 列的x、y坐标作为位置参数,同时以向量的形式指定要放置的文本。x、y和文本标签向量的长度 应当相同。
例子
attach(mtcars)
plot(wt, mpg,
main="Mileage vs. Car Weight",
xlab="Weight", ylab="Mileage",
pch=18, col="blue")
text(wt, mpg,
row.names(mtcars),
cex=0.6, pos=4, col="red") #函数text()被用来在各个数据点右侧添加车辆型号。各点的标签大小被缩小了40%,颜色为红色。
detach(mtcars)
不同字体族
opar <- par(no.readonly=TRUE)
par(cex=1.5)
plot(1:7,1:7,type="n")
text(3,3,"Example of default text")
text(4,4,family="mono","Example of mono-spaced text")
text(5,5,family="serif","Example of serif text")
par(opar)
3.4.6 数学标注:函数plotmath()可以为图形主体或边界上的标题、坐标轴名称 或文本标注添加数学符号
你可以使用类似于 TeX 中的写法为图形添加数学符号和公式。请参阅 help(plotmath)以获得更多细节和示例。要即时看效果,可以尝试执行demo(plotmath)。 部分运行结果如图3-13所示。
3.5 图形的组合:将多幅图形组合为一幅图形的方法
在R中使用函数par()或layout()可以容易地组合多幅图形为一幅总括图形。
- 此时请不要担 心所要组合图形的具体类型,这里我们只关注组合它们的一般方法。后续各章将讨论每类图形的 绘制和解读问题。
你可以在par()函数中使用图形参数mfrow=c(nrows, ncols)来创建按行填充的、行数为 nrows、列数为ncols的图形矩阵。
另外,可以使用mfcol=c(nrows, ncols)按列填充矩阵。
例子
attach(mtcars)
opar <- par(no.readonly=TRUE)
par(mfrow=c(2,2))
plot(wt,mpg, main="Scatterplot of wt vs. mpg")
plot(wt,disp, main="Scatterplot of wt vs. disp")
hist(wt, main="Histogram of wt")
boxplot(wt, main="Boxplot of wt")
par(opar)
detach(mtcars)
例子2:作为第二个示例,让我们依三行一列排布三幅图形。
注意:高级绘图函数hist()包含了一个默认的标题(使用main=""可以禁用它,抑或使用ann=FALSE来禁用所有标题和标签)
attach(mtcars)
opar <- par(no.readonly=TRUE)
par(mfrow=c(3,1))
hist(wt)
hist(mpg)
hist(disp)
par(opar)
detach(mtcars)
函数layout()的调用形式为layout(mat),其中的mat是一个矩阵,它指定了所要组合的 多个图形的所在位置。
attach(mtcars)
layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
hist(wt)
hist(mpg)
hist(disp)
detach(mtcars)
为了更精确地控制每幅图形的大小,可以有选择地在layout()函数中使用widths=和 heights=两个参数。其形式为:
widths = 各列宽度值组成的一个向量
heights = 各行高度值组成的一个向量
例子
在以下代码中,我们再次将一幅图形置于第1行,两幅图形置于第2行。但第1行中图形的 高度是第2行中图形高度的二分之一。除此之外,右下角图形的宽度是左下角图形宽度的三分 之一:
attach(mtcars)
layout(matrix(c(1, 1, 2, 3), 2, 2, byrow = TRUE),
widths=c(3, 1), heights=c(1, 2))
hist(wt)
hist(mpg)
hist(disp)
detach(mtcars)
layout():调整位置和相对大小
图形布局的精细控制
可能有很多时候,你想通过排布或叠加若干图形来创建单幅的、有意义的图形,这需要有对 图形布局的精细控制能力。你可以使用图形参数fig=完成这个任务。
代码清单3-4通过在散点图 上添加两幅箱线图,创建了单幅的增强型图形。
例子:
原理:
请试想完整的绘图区域:左下角坐标为(0, 0),而右上角坐标为 (1, 1)。图3-19是一幅示意图。
参数fig=的取值是一个形如c(x1, x2, y1, y2)的数值向量。
opar <- par(no.readonly=TRUE)
par(fig=c(0, 0.8, 0, 0.8))
plot(mtcars$wt, mtcars$mpg,
xlab="Miles Per Gallon",
ylab="Car Weight") #散点图
par(fig=c(0, 0.8, 0.55, 1), new=TRUE)
boxplot(mtcars$wt, horizontal=TRUE, axes=FALSE) #在上面加箱型图
par(fig=c(0.65, 1, 0, 0.8), new=TRUE)
boxplot(mtcars$mpg, axes=FALSE) # 在右侧加箱型图
mtext("Enhanced Scatterplot", side=3, outer=TRUE, line=-3)
par(opar)
第一个fig=将散点图设定为占据横向范围0~0.8,纵向范围0~0.8。
上方的箱线图横向占据 0~0.8,纵向0.55~1。右侧的箱线图横向占据0.65~1,纵向0~0.8。fig=默认会新建一幅图形,所 以在添加一幅图到一幅现有图形上时,请设定参数new=TRUE。
我将参数选择为0.55而不是0.8,这样上方的图形就不会和散点图拉得太远。
类似地,我选择 了参数0.65以拉近右侧箱线图和散点图的距离。你需要不断尝试找到合适的位置参数
可能的报错
各独立子图所需空间的大小可能与设备相关。如果你遇到了“Error in plot.new(): figure margins too large”这样的错误,请尝试在整个图形的范围内修改各个子图占据的区域位 置和大小。