3.4 添加文本、自定义坐标轴和图例

除了图形参数,许多高级绘图函数(例如plothistboxplot)也允许自行设定坐标轴和文本标注选项。举例来说,以下代码在图形上添加了标题(main)、副标题(sub)、坐标轴标签(xlabylab)并指定了坐标轴范围(xlimylim)。结果如图3-8所示。

  1. plot(dose, drugA, type="b",
  2. col="red", lty=2, pch=2, lwd=2,
  3. main="Clinical Trials for Drug A",
  4. sub="This is hypothetical data",
  5. xlab="Dosage", ylab="Drug Response",
  6. xlim=c(0, 60), ylim=c(0, 70))

3.4 添加文本、自定义坐标轴和图例 - 图1

图3-8 药物A剂量和响应的折线图。添加了标题、副标题和自定义的坐标轴

再次提醒,并非所有函数都支持这些选项。请参考相应函数的帮助以了解其可以接受哪些选项。从更精细的控制和模块化的角度考虑,你可以使用本节余下部分描述的函数来控制标题、坐标轴、图例和文本标注的外观。

注意 某些高级绘图函数已经包含了默认的标题和标签。你可以通过在plot()语句或单独的par()语句中添加ann=FALSE来移除它们。

3.4.1 标题

可以使用title()函数为图形添加标题和坐标轴标签。调用格式为:

  1. title(main="main title", sub="sub-title",
  2. xlab="x-axis label", ylab="y-axis label")

函数title()中亦可指定其他图形参数(如文本大小、字体、旋转角度和颜色)。举例来说,以下代码将生成红色的标题和蓝色的副标题,以及较默认大小小25%的绿色x轴、y轴标签:

  1. title(main="My Title", col.main="red",
  2. sub="My Sub-title", col.sub="blue",
  3. xlab="My X label", ylab="My Y label",
  4. col.lab="green", cex.lab=0.75)

3.4.2 坐标轴

你可以使用函数axis()来创建自定义的坐标轴,而非使用R中的默认坐标轴。其格式为:

  1. axis(side, at=, labels=, pos=, lty=, col=, las=, tck=, ...)

各参数已详述于表3-7中。 表3-7 坐标轴选项

选  项 描  述
side 一个整数,表示在图形的哪边绘制坐标轴(1=下,2=左,3=上,4=右)
at 一个数值型向量,表示需要绘制刻度线的位置
labels 一个字符型向量,表示置于刻度线旁边的文字标签(如果为NULL,则将直接使用at中的值)
pos 坐标轴线绘制位置的坐标(即与另一条坐标轴相交位置的值)
lty 线条类型
col 线条和刻度线颜色
las 标签是否平行于(=0)或垂直于(=2)坐标轴
tck 刻度线的长度,以相对于绘图区域大小的分数表示(负值表示在图形外侧,正值表示在图形内侧,0表示禁用刻度,1表示绘制网格线);默认值为-0.01
(…) 其他图形参数

创建自定义坐标轴时,你应当禁用高级绘图函数自动生成的坐标轴。参数axes=FALSE将禁用全部坐标轴(包括坐标轴框架线,除非你添加了参数frame.plot=TRUE)。参数xaxt="n"yaxt="n"将分别禁用X轴或Y轴(会留下框架线,只是去除了刻度)。代码清单3-2中是一个稍显笨拙和夸张的例子,它演示了我们到目前为止讨论过的各种图形特征。结果如图3-9所示。

代码清单3-2 自定义坐标轴的示例

  1. x <- c(1:10) # 生成数据
  2. y <- x
  3. z <- 10/x
  4. opar <- par(no.readonly=TRUE)
  5. par(mar=c(5, 4, 4, 8) + 0.1) # 增加边界大小
  6. plot(x, y, type="b", # 绘制x对y的图形
  7. pch=21, col="red",
  8. yaxt="n", lty=3, ann=FALSE)
  9. lines(x, z, type="b", pch=22, col="blue", lty=2) # 添加x对1/x的直线
  10. axis(2, at=x, labels=x, col.axis="red", las=2) # 绘制你自己的坐标轴
  11. axis(4, at=z, labels=round(z, digits=2),
  12. col.axis="blue", las=2, cex.axis=0.7, tck=-.01)
  13. mtext("y=1/x", side=4, line=3, cex.lab=1, las=2, col="blue") # 添加标题和文本
  14. title("An Example of Creative Axes",
  15. xlab="X values",
  16. ylab="Y=X")
  17. par(opar)

3.4 添加文本、自定义坐标轴和图例 - 图2

图3-9 各种坐标轴选项的演示

到目前为止,我们已经讨论过代码清单3-2中除lines()mtext()以外的所有函数。使用plot()语句可以新建一幅图形。而使用lines()语句,你可以为一幅现有图形添加新的图形元素。在3.4.4节中,你会再次用到它,在同一幅图中绘制药物A和药物B的响应情况。函数mtext()用于在图形的边界添加文本。我们将在3.4.5节中讲到函数mtext(),同时会在第11章中更充分地讨论lines()函数。

次要刻度线

注意,我们最近创建的图形都只拥有主刻度线,却没有次要刻度线。要创建次要刻度线,你需要使用Hmisc包中的minor.tick()函数。如果你尚未安装Hmisc包,请先安装它(参考1.4.2节)。你可以使用代码:

  1. library(Hmisc)
  2. minor.tick(nx=n, ny=n, tick.ratio=n)

来添加次要刻度线。其中nxny分别指定了X轴和Y轴每两条主刻度线之间通过次要刻度线划分得到的区间个数。tick.ratio表示次要刻度线相对于主刻度线的大小比例。当前的主刻度线长度可以使用par("tck")获取。举例来说,下列语句将在X轴的每两条主刻度线之间添加1条次要刻度线,并在Y轴的每两条主刻度线之间添加2条次要刻度线:

  1. minor.tick(nx=2, ny=3, tick.ratio=0.5)

次要刻度线的长度将是主刻度线的一半。3.4.4节中给出了添加次要刻度线的一个例子(代码清单3-3和图3-10)。

3.4.3 参考线

函数abline()可以用来为图形添加参考线。其使用格式为:

  1. abline(h=yvalues, v=xvalues)

函数abline()中也可以指定其他图形参数(如线条类型、颜色和宽度)。举例来说:

  1. abline(h=c(1,5,7))

在y为1、5、7的位置添加了水平实线,而代码:

  1. abline(v=seq(1, 10, 2), lty=2, col="blue")

则在x为1、3、5、7、9的位置添加了垂直的蓝色虚线。代码清单3-3为我们的药物效果图在 y = 30的位置创建了一条参考线。结果如图3-10所示。

3.4.4 图例

当图形中包含的数据不止一组时,图例可以帮助你辨别出每个条形、扇形区域或折线各代表哪一类数据。我们可以使用函数legend()来添加图例(果然不出所料)。其使用格式为:

  1. legend(location, title, legend, ...)

常用选项详述于表3-8中。 表3-8 图例选项

选  项 描  述
location 有许多方式可以指定图例的位置。你可以直接给定图例左上角的x、y坐标,也可以执行locator(1),然后通过鼠标单击给出图例的位置,还可以使用关键字bottombottomleftlefttoplefttoptoprightrightbottomrightcenter放置图例。如果你使用了以上某个关键字,那么可以同时使用参数inset=指定图例向图形内侧移动的大小(以绘图区域大小的分数表示)
title 图例标题的字符串(可选)
legend 图例标签组成的字符型向量
其他选项。如果图例标示的是颜色不同的线条,需要指定col=加上颜色值组成的向量。如果图例标示的是符号不同的点,则需指定pch=加上符号的代码组成的向量。如果图例标示的是不同的线条宽度或线条类型,请使用lwd=lty=加上宽度值或类型值组成的向量。要为图例创建颜色填充的盒形(常见于条形图、箱线图或饼图),需要使用参数fill=加上颜色值组成的向量

其他常用的图例选项包括用于指定盒子样式的bty、指定背景色的bg、指定大小的cex,以及指定文本颜色的text.col。指定horiz=TRUE将会水平放置图例,而不是垂直放置。关于图例的更多细节,请参考help(legend)。这份帮助中给出的示例都特别有用。

让我们看看对药物数据作图的一个例子(代码清单3-3)。你将再次使用我们目前为止讲到的许多图形功能。结果如图3-10所示。

代码清单3-3 依剂量对比药物A和药物B的响应情况

  1. dose <- c(20, 30, 40, 45, 60)
  2. drugA <- c(16, 20, 27, 40, 60)
  3. drugB <- c(15, 18, 25, 31, 40)
  4. opar <- par(no.readonly=TRUE)
  5. par(lwd=2, cex=1.5, font.lab=2) # 增加线条、文本、符号、标签的宽度或大小
  6. plot(dose, drugA, type="b",
  7. pch=15, lty=1, col="red", ylim=c(0, 60), # 绘制图形
  8. main="Drug A vs. Drug B",
  9. xlab="Drug Dosage", ylab="Drug Response")
  10. lines(dose, drugB, type="b",
  11. pch=17, lty=2, col="blue")
  12. abline(h=c(30), lwd=1.5, lty=2, col="gray")
  13. library(Hmisc) # 添加次要刻度线
  14. minor.tick(nx=3, ny=3, tick.ratio=0.5)
  15. legend("topleft", inset=.05, title="Drug Type", c("A","B"), # 添加图例
  16. lty=c(1, 2), pch=c(15, 17), col=c("red", "blue"))
  17. par(opar)

3.4 添加文本、自定义坐标轴和图例 - 图3

图3-10 进行标注后的图形,对比了药物A和药物B的效果

图3-10的几乎所有外观元素都可以使用本章中讨论过的选项进行修改。除此之外,还有很多其他方式可以指定想要的选项。最后一种需要研究的图形标注是向图形本身添加文本,请继续读下一节。

3.4.5 文本标注

我们可以通过函数text()mtext()将文本添加到图形上。text()可向绘图区域内部添加文本,而mtext()则向图形的四个边界之一添加文本。使用格式分别为:

  1. text(location, "text to place", pos, ...)
  2. mtext("text to place", side, line=n, ...)

常用选项列于表3-9中。 表3-9 函数text()mtext()的选项

选  项 描  述
location 文本的位置参数。可为一对x,y坐标,也可通过指定locationlocator(1)使用鼠标交互式地确定摆放位置
pos 文本相对于位置参数的方位。1=下,2=左,3=上,4=右。如果指定了pos,就可以同时指定参数offset=作为偏移量,以相对于单个字符宽度的比例表示
side 指定用来放置文本的边。1=下,2=左,3=上,4=右。你可以指定参数line=来内移或外移文本,随着值的增加,文本将外移。也可使用adj=0将文本向左下对齐,或使用adj=1右上对齐

其他常用的选项有cexcolfont(分别用来调整字号、颜色和字体样式)。

除了用来添加文本标注以外,text()函数也通常用来标示图形中的点。我们只需指定一系列的x, y坐标作为位置参数,同时以向量的形式指定要放置的文本。x、y和文本标签向量的长度应当相同。下面给出了一个示例,结果如图3-11所示。

  1. attach(mtcars)
  2. plot(wt, mpg,
  3. main="Mileage vs. Car Weight",
  4. xlab="Weight", ylab="Mileage",
  5. pch=18, col="blue")
  6. text(wt, mpg,
  7. row.names(mtcars),
  8. cex=0.6, pos=4, col="red")
  9. detach(mtcars)

3.4 添加文本、自定义坐标轴和图例 - 图4

图3-11 一幅散点图(车重与每加仑汽油行驶英里数)的示例,各点均添加了标签(车型)

这里,我们针对数据框mtcars提供的32种车型的车重和每加仑汽油行驶英里数绘制了散点图。函数text()被用来在各个数据点右侧添加车辆型号。各点的标签大小被缩小了40%,颜色为红色。

作为第二个示例,以下是一段展示不同字体族的代码:

  1. opar <- par(no.readonly=TRUE)
  2. par(cex=1.5)
  3. plot(1:7,1:7,type="n")
  4. text(3,3,"Example of default text")
  5. text(4,4,family="mono","Example of mono-spaced text")
  6. text(5,5,family="serif","Example of serif text")
  7. par(opar)

在Windows系统中输出的结果如图3-12所示。这里为了获得更好的显示效果,我们使用par()函数增大了字号。

3.4 添加文本、自定义坐标轴和图例 - 图5

图3-12 Windows中不同字体族的示例

本例所得结果因平台而异,因为不同系统中映射的常规字体、等宽字体和有衬线字体有所不同。在你的系统上,结果看起来如何呢?

数学标注

最后,你可以使用类似于TeX中的写法为图形添加数学符号和公式。请参阅help(plotmath)以获得更多细节和示例。要即时看效果,可以尝试执行demo(plotmath)。部分运行结果如图3-13所示。函数plotmath()可以为图形主体或边界上的标题、坐标轴名称或文本标注添加数学符号。

3.4 添加文本、自定义坐标轴和图例 - 图6

图3-13 demo(plotmath)的部分结果

同时比较多幅图形,我们通常可以更好地洞察数据的性质。所以,作为本章的结尾,下面讨论将多幅图形组合为一幅图形的方法。