图形

常用图形

S-PLUS有很强的图形功能,它可以用简单的函数调用迅速作出数据的各种图形,当你 熟悉了S图形的技术之后也可以指定许多图形选项按自己的要求定制图形。它的另一个特色是 同一个绘图函数对不同的数据对象可以作出不同的图形。例如,用7.1.2读入的cl数据框:

> plot(cl)
> plot(cl[,1])

第一个plot()调用绘制cl中三个列的散点图矩阵,第二个plot()调用绘制身高的散点图( 纵轴为身高值,横轴为下标)。

最常用的绘图函数为plot(),用plot()作两个变量x与y的散点图,使用如下例的方法:

> attach(cl)
> plot(Height, Weight, main="体重对身高的回归",
+ xlab="身高", ylab="体重")

上例在R中运行成功(见图2),在S-PLUS中请将汉字字符串改为英文。上例也演示了S中 如何输入较长的语句:只要语句明显地未完成(比如,缺右括号),系统将给出一个加号作 为续行提示。如果输入“x <- 1+2”时要拆行,可以在赋值号后拆,可以在加号与2之间 拆,但是如果在x后拆则只能显示x的当前值,如果在1与加号之间拆只能把1赋给x。

为了绘制连线图,只要在plot()函数中加type="l"选项,如:

> plot((1:50)/50, log((1:50)/50), type="l")
可以绘制变量的茎叶图,如:
> stem(Weight)
 
  The decimal point is 1 digit(s) to the right of the |
 
   4 | 1
   6 | 7
   8 | 3445508
  10 | 0332233
  12 | 83
  14 | 0

绘制一个变量的盒形图,如:

> boxplot(Weight)

结果见图3。可以绘制几个变量并排的盒形图,比如先计算用上面的回归拟合结果存入p1 ,然后绘制并排盒形图:

> p1 <- predict(fit1, cl)[,"predictor"]
> boxplot(Weight, p1)

用hist()函数可以绘制直方图。例如:

> hist(Weight)
得图4。

用qqnorm()函数绘制正态概率图,如:

> qqnorm(Weight)
得图5。

高级图形函数

S的图形函数分为两类:高级图形函数――直接绘制图形并可自动生成坐标轴等附属 图形元素;低级图形函数――可以修改已有的图形或者为绘图规定一些选择项。高级图形函 数总是开始一个新图。下面我们介绍常用的高级图形函数,以及用来修饰这些高级图形函数 的常用可选参数。

最常用的是plot()函数。比如,plot(x,y)(其中x,y是向量)对两个变量画散点图。用plot(z) (其中z是一个定义了x变量和y变量的列表,或者一个两列的矩阵)也可以达到同样目的。如 果x是一个时间序列对象(时间序列对象用ts()函数生成),plot(x)绘制时间序列曲线图。 如果x是一个普通向量,则绘制x的值对其下标的散点图。如果x是复数向量则绘制虚部对实部 的散点图。如果f是一个因子,则plot(f)绘制f的条形图(每个因子水平的个数)。如果f是 因子,y是同长度的数值向量,则plot(f,y)对f的每一因子水平绘制y中相应数值的盒形图。 如果d是一个数据框,则plot(d)对d的每两个变量之间作图(散点图等)。

如果X是一个数值型矩阵或数据框,用pairs(X)可以绘制每两列之间的散点图矩阵。这在 变量个数不太多时可以同时看到多个变量的两两关系,变量太多时则难以绘制。

协同图(coplot)是一种多变量的探索性分析图形。其形式为coplot(y ~ x | z),其中x 和y是数值型向量,z是同长度的因子。对z的每一水平,绘制相应组的x和y的散点图。如:

> attach(cl)
> coplot(Weight ~ Height | Sex)

产生图6。对不同性别分别绘制了体重对身高的散点图。如果z是一个数值型变量,则coplot() 先对z的取值分组,然后对z的每一组取值分别绘图。甚至可以用如coplot(y~x | x1+x2)表示 对x1和x2的每一水平组合绘图。coplot()和pairs()函数缺省绘制散点图,但可以用一个panel= 参数指定其它的低级绘图函数,如lines,panel.smooth等。

tsplot(x)绘制时间序列曲线图。多个参数时tsplot(x1, x2, ...)表示绘制多条曲线 ,自动统一曲线取值范围。如果参数非时间序列对象则以下标1,2,3等为横坐标绘图。

qqnorm(x), qqline(x), qqplot(x,y)作分位数-分位数图。qqnorm(x)对向量x作正 态概率(纵轴为次序统计量值,横轴为对应该次序统计量的标准正态分布分位数值)。qqline(x) 除作qqnorm(x)图之外还画一条拟合曲线。qqplot(x,y)把x和y的次序统计量分别画在x轴和y 轴以比较两个变量的分布。

hist(x)作向量x的直方图。缺省时自动确定分组,也可以用nclass=参数指定分组个 数,或者用breaks=参数指定一个分组点向量。如果指定了prob=T则纵轴显示密度估计。

S也可以作三维图或等值线图,函数为persp()和contour(),见图7和图8。

高级图形函数的常用选项

高级图形函数有一些共同的选项,作为函数的可选参数(自变量)。例如:

> plot(x)

> plot(x, main="Graph of x")

其中的main就是一个可选参数,用来指定图形的标题。没有此选项时图形就没有标题。这 样的选项还有:

add=T

使函数向低级图形函数那样不是开始一个新图形而是在原图基础上添加。

axes=F

暂不画坐标轴,随后可以用axis()函数更精确地规定坐标轴的画法。缺省值是axes=T,即 有坐标轴。

log="x"
log="y"

log="xy"

把x轴,y轴或两个坐标轴用对数刻度绘制。

type=

  • type="p"

  • type="l"
  • type="b"
  • type="o"
  • type="h"
  • type="s"
  • type="S"
  • type="n"

规定绘图方式:

  • 绘点
  • 画线
  • 绘点并在中间用线连接
  • 绘点并画线穿过各点
  • 从点到横轴画垂线
  • 阶梯函数;左连续
  • 阶梯函数;右连续
  • 不画任何点、线,但仍画坐标轴并建立坐标系,适用于后面用低级图形函数作图。
xlab="字符串"
ylab="字符串"
main="字符串"

sub="字符串"

定义x轴和y轴的标签。缺省时使用对象名。
 
图形的标题。

图形的小标题,用较小字体画在x轴下方。

低级图形函数

高级图形函数可以迅速简便地绘制常见类型的图形,但是,某些情况下你可能希望绘 制一些有特殊要求的图形。比如,你希望坐标轴按照自己的设计绘制,在已有的图上增加另 一组数据,在图中加入一行文本注释,绘出多个曲线代表的数据的标签,等等。低级图形函 数让你在已有的图的基础上进行添加。

常用的低级图形函数罗列如下:

points(x,y)

lines(x,y)

在当前图形上叠加一组点或线。可以使用plot()的type=参数来指定绘制方法,缺省时points() 画点,lines()画线。

text(x,y, labels, ...)

在由坐标x和y给出的位置标出由labels指定的字符串。labels可以是数值型或字符型的向 量,labels[i]在x[i],y[i]处标出。

abline(a, b)
abline(h=y)
abline(v=x)

abline( lm.obj)

在当前图形上画一条直线。两个参数a, b分布给出截距和斜率。指定h=参数时绘制水平线 ,指定v=参数时绘制垂直线。以一个最小二乘拟合结果lm.obj作为参数时由lm.obj的$coefficients 成员给出直线的截距和斜率。

polygon(x, y, ...)

以由向量x给出的横坐标和向量y给出的纵坐标为顶点绘制多边形。可以用col=参数指定一 个颜色填充多边形内部。

legend(x, y, 
    legend, ...)
 
legend(,
    angle=v)
legend(, 
    density=v)
legend( , fill=v)
legend(, col=v)
legend(, lty=v)
legend(, pch=v)
legend(,
    marks=v)

legend函数用来在当前图形的指定坐标位置绘制图例。图例的说明文字由向量legend提供 。至少下面的v值要给出以确定要对什么图例进行说明,v是长度与legend相同的向量。

angle参数指定几种阴影斜角。
 
density参数指定几种阴影密度。
 
fill参数指定几种填充颜色。
col参数指定几种颜色。
lty参数指定几种线型。
pch参数指定几种散点符号。为字符型向量。
 

marks参数也指定几种散点符号,但使用散点符号数值代号,为数值型向量。

title(main, sub)

绘制由main指定的标题和由sub指定的小标题。

axis(side, ...)

绘制一条坐标轴。这之前的绘图函数必须已经用axes=F选项抑制了自动的坐标轴。参数side 指定在哪一边绘制坐标轴,取值为1到4,1为下边,然后逆时针数。可以用at=参数指定刻度 位置,用labels参数指定刻度处的标签。

低级图形函数一般需要指定位置信息,其中的坐标指的是所谓用户坐标,即前面的高级图 形函数所建立的坐标系中的坐标。坐标可以用两个向量x和y给出,也可以由一个两列的矩阵 给出。如果交互作图可以用下面介绍的locator()函数来交互地从图形中直接输入坐标位置。

交互图形函数

S的低级图形函数可以在已有图形的基础上添加新内容,另外,S还提供了两个函数locator 和identify可以让用户通过在图中用鼠标点击来确定位置。

函数locator(n, type)运行时会停下来等待用户在图中点击,然后返回图形中鼠标点击的 位置的坐标。等待点击时用鼠标中键点击可以选择停止等待,立即返回。参数n指定点击多少 次后自动停止,缺省为500次;参数type如果使用则可指定绘点类型,与plot()函数中的type 参数用法相同,在鼠标点击处绘点(线、垂线,等等)。locator()的返回值是一个列表,有 两个变量(元素)x和y,分别保存点击位置的横坐标和纵坐标。

例如,为了在已经绘制的曲线图中找一个空地方标上一行文本,只要使用如下程序:

> text(locator(1), "Normal density", adj=0)

text()函数的adj参数用一个数字表示文本串相对于给定的坐标的画法,adj=0表示给定坐 标为文本串左侧的坐标,adj=1表示给定坐标为文本串右侧的坐标,adj=0.5表示给定坐标为 文本串中间的坐标。

函数identify(x, y, labels)在运行时也会停下来等待用户点击,直到按了鼠标中键,任 何返回用户在图形中用鼠标点击的点的序号,点击时对点击的点加标签。参数x和y给出要识 别的各个点的坐标。labels参数指定点击某个点时要在旁边绘制的文本标签,缺省时标出此 点的序号,如果只需要返回值而不想画任何标记则可以在调用此函数时加一个plot=F参数。 注意identify()与locator()不同,locator()返回图中任意点击位置的坐标,而identify() 只返回离点击位置最近的点的序号。

例如,我们在向量x和y中有若干个点的坐标,运行如下程序:

> plot(x, y)
> identify(x, y)

这时显示转移到图形窗口,进入等待状态,用户可以点击图中特别的点,该点的序号就会 在旁边标出。为了结束,只要单击鼠标中键或单击右键并选择停止。返回结果为你点击的各 个点的序号:

[1] 4 6 7 8

图形参数的使用

前面我们已经看到了如何用main=,xlab=等参数来规定高级图形函数的一些设置。在 实际绘图,特别是绘制用于演示或出版的图形时,S用缺省设置绘制的图形往往不能满足我们 的要求。但是,S提供了一系列所谓图形参数,通过使用图形参数可以修改图形显示的所有各 方面的设置。图形参数包括关于线型、颜色、图形排列、文本对齐方式等各种设置。每个图 形参数有一个名字,比如col代表颜色,取一个值,比如col="red"是红色。每个图形设备有 一套单独的图形参数。

设置图形参数分为两种:永久设置与临时设置。永久设置使用par()函数进行设置,设置 后在退出前一直保持有效;临时设置则是在图形函数中加入图形参数,如上面的例子:

> text(locator(1), "Normal density", adj=0)
中的adj参数。

par()函数用来访问或修改当前图形设备的图形参数。如果不带参数调用,如:

> par()
$adj
[1] 0.5
 
$ann
[1] 1
 
………………
 
$tcl
[1] -0.5
结果为一个列表,列表的各元素名为图形参数的名字,元素值为相应图形参数的取值。

如果调用时指定一个图形参数名的向量作为参数,则只返回被指定的图形参数的列表:

> par(c("col", "lty"))
$col
[1] "black"
 
$lty
[1] "solid"

调用时指定名字为图形参数名的有名参数,则修改指定的图形参数,并返回原值的列 表:

> oldpar <- par(col=4, lty=2)
> oldpar
$col
[1] "black"
 
$lty
[1] "solid"

因为用par()修改图形参数是保持到退出以前都有效的,而且即使是在函数内此修改 仍是全局的,所以我们可以利用如下的惯用法,在完成任务后恢复原来的图形参数:

> oldpar <- par(col=4, lty=2)
………………(需要修改图形参数的绘图任务)
> par(oldpar)    # 恢复原始的图形参数

除了象上面那样用par()函数永久修改图形参数,我们还可以在几乎任何图形函数中 指定图形参数作为有名参数,这样的修改是临时的,只对此函数起作用。例如:

> plot(x, y, pch="+")

就用图形参数pch指定了绘散点的符号为加号。这个设定只对这一张图有效,对以后的图 形没有影响。

图形参数详解

鉴于绘制有特殊需要的图形是S的一个强项,而使用图形参数是完成此类任务的重要 手段,我们在这里较详细地介绍S的各种图形参数。这些图形参数可以大体上分为以下的几个 大类,我们将分别介绍:

 

一、图形元素

图形由点、线、文本、多边形等元素构成。下列的图形参数用来控制图形元素的绘制 细节:

pch="+"
 
 

pch=4

指定用于绘制散点的符号。绘制的点往往略高于或低于指定的坐标位置,只有pch="."没 有这个问题。

 

如果pch的值为从0到18之间的一个数字,将使用特殊的绘点符号。下例可以显示所有特殊 绘点符号:

> plot(c(0, 100), c(0, 100), type="n", axes=F, xlab='', ylab='')
> legend(10,90, as.character(0:9), pch=0:9)
> legend(50,90, as.character(10:18), pch=10:18)

lty=2

指定画线用的线型。缺省值lty=1是实线。从2开始是各种虚线。

lwd=2

指定线粗细,以标准线粗细为单位。这个参数影响数据曲线的线宽以及坐标轴的线宽。下 例绘制正弦曲线图:

> oldpar <- par(lwd=2)
> x <- (0:100)/100*2*pi
> plot(x, sin(x), type="l", axes=F)
> abline(h=0)
> abline(v=0)
> par(oldpar)

col=2

指定颜色,可应用于绘点、线、文本、填充区域、图象。颜色值也可以用象"red","blue" 这样的颜色名指定。

font=2

用来指定字体的整数。一般font=1是正体,2是 黑体,3是 斜体,4是 黑斜体

font.axis
font.lab
font.main

font.sub

分别用来指定坐标刻度、坐标轴标签、标题、小标题所用的字体。

adj=-0.1

指定文本相对于给定坐标的对齐方式。取0表示左对齐,取1表示右对齐,取0.5表示居中 。此参数的值实际代表的是出现在给定坐标左边的文本的比例,所以adj=-0.1的效果是文本 出现在给定坐标位置的右边并空出相当于文本10%长度的距离。

cex=1.5

指定字符放大倍数。

 

二、坐标轴与坐标刻度

许多高级图形带有坐标轴,还可以先不画坐标轴然后用axis()单独加。函数box() 用来画坐标区域四周的框线。

坐标轴包括三个部件:轴线(用lty可以控制线型),刻度线,刻度标签。它们可以 用如下的图形参数来控制:

lab=c(5, 7, 12)

第一个数为x轴希望画几个刻度线,第二个数为y轴希望画几个刻度线,这两个数是建议性 的;第三个数是坐标刻度标签的宽度为多少个字符,包括小数点,这个数太小会使刻度标签 四舍五入成一样的值。

las=1

坐标刻度标签的方向。0表示总是平行于坐标轴,1表示总是水平,2表示总是垂直于坐标 轴。

mgp=c(3,1,0)

坐标轴各部件的位置。第一个元素为坐标轴位置到坐标轴标签的距离,以文本行高为单位 。第二个元素为坐标轴位置到坐标刻度标签的距离。第三个元素为坐标轴位置到实际画的坐 标轴的距离,通常是0。

tck=0.01

坐标轴刻度线长度,单位是绘图区域大小,值为占绘图区域的比例。tck小于0.5时x轴和y 轴的刻度线将统一到相同的长度。取1时即画格子线。取负值时刻度线画在绘图区域的外面。

xaxs="s"

yaxs="d"

控制x轴和y轴的画轴方法。

取值为"s"(即standard)或"e"(即extended)的时候数据范围控制在最小刻度和最大刻 度之间。取"e"时如果有数据点十分靠近边缘轴的范围会略微扩大。这种画轴方式有时会在轴 的一边留下太大的空白。

取值为"i"(即internal)或"r"(此为缺省)使得刻度线都落在数据范围内部,而"r"方 式所留的边空较小。

取值设为"d"时会锁定此坐标轴,后续的图形都使用与它完全相同的坐标轴,这在要生成 一系列可比较的图形的时候是有用的。要解除锁定需要把这个图形参数设为其它值。

三、图形边空

S中一个单独的图由绘图区域(绘图的点、线等画在这个区域中)和包围绘图区 域的边空组成,边空中可以包含坐标轴标签、坐标轴刻度标签、标题、小标题等,绘图区域 一般被坐标轴包围。见图9。

边空的大小由mai参数或mar参数控制,它们都是四个元素的向量,分别规定下方、左 方、上方、右方的边空大小,其中mai取值的单位是英寸,而mai的取值单位是文本行高度。 例如:

> par(mai=c(1, 0.5, 0.5, 0))

> par(mar=c(4, 2, 2, 1))

这两个图形参数不是独立的,设定一个会影响另一个。S缺省的图形边空常常太大, 以至于有时图形窗口较小时边空占了整个图形的很大一部分。通常我们可以取消右边空,并 且在不用标题时可以大大缩小上边空。例如下例可以生成十分紧凑的图形:

> oldpar <- par(mar=c(2,2,1,0.2))

> plot(x,y)

在一个页面上画多个图时边空自动减半,但我们往往还需要进一步减小边空才能使多 个图有意义。

 

四、一页多图

R可以在同一页面开若干个按行、列排列的窗格,在每个窗格中可以作一幅图。 每个图有自己的边空,而所有图的外面可以包一个“外边空”,见图10。

一页多图用mfrow参数或mfcol参数规定,如:

> par(mfrow=c(3,2))

表示同一页有三行两列共六个图,而且次序为按行填放。类似地,

> par(mfcol=c(3,2))

规定相同的窗格结构,但是次序为按列填放,即先填满第一列的三个再填第二列。要取消 一页多图只要再运行

> par(mfrow=c(1,1))

即可。

缺省时无外边空。为了规定外边空大小,可以用omi参数或oma参数。omi参数使用英 寸为单位,oma参数以文本行高为单位,两个参数均为四个元素的向量,分别给出下、左、上 、右方的边空大小。如:

> par(oma=c(2,0,3,0))

函数mtext用来在外边空加文字标注。其用法为

mtext(text, side = 3, line = 0, outer = FALSE)

其中text为要加的文本内容,side表示在哪一边写(1为下,2为左,3为上,4为右),line 表示边空从里向外数的第几行,最里面的一行是第0号,outer=TRUE时使用外边空,否则会使 用当前图的边空。例如:

> par(mfrow=c(2,2), oma=c(0,0,3,0), mar=c(2,1,1,0.1))
> plot(x);plot(y);boxplot(list(x=x,y=y));plot(x,y)
> mtext("Simulation Data", outer=T, cex=1.5)

在多图环境中还可以用mfg参数来直接跳到某一个窗格,比如

> par(mfg=c(2,2,3,2))

表示在三行两列的多图环境中直接跳到第二行第二列位置。mfg参数的后两个表示多图环 境的行、列数,前两个表示要跳到的位置。

可以不使用多图环境而直接在页面中的任意位置产生一个窗格来绘图,参数为fig, 如:

> par(fig=c(4,9,1,4)/10)

此参数为一个向量,分别给出窗格的左、右、下、上边缘的位置,取值为占全页面的比例 ,比如上面的例子在页面的右下方开一个窗格作图。

图形设备

S作图支持各种图形设备,其中常用的是显示器和PostScript打印机。在一个S运行期 间可以有多个图形设备同时存在。在R中,用

> x11()

打开图形窗口绘图,在S-PLUS中,用

> win.graph()

打开图形窗口绘图。再次调用这样的函数将打开第二个图形窗口。用

> dev.list()

可显示以打开的图形设备的列表。

要关闭一个图形设备,用

> dev.off()

这可以使得图形得以完成,例如对于postscript设备关闭设备时可完成打印或存盘。用graphics.off() 函数可以关闭所有打开的图形设备。

MS Windows下的R可以把显示窗口中的图形复制到剪贴板或存为各种格式的图形文件 ,包括WMF、PostScript、PNG、BMP、JPEG,这样我们可以用R生成所需图形然后存为需要的 格式。MS Windows下的S-PLUS也具有类似功能。

各版本的R和S-PLUS都支持生成PostScript图形的功能,生成的图形可以直接用于LaTeX 排版。如果用MS Word排版则可把屏幕图形存为WMF等格式。生成PostScript文件的设备可以 用如下函数打开:

> postscript(file="result1.ps", horizontal=FALSE, width=5, height=3)

这时用图形命令生成一个页面的图形,然后用dev.off()关闭设备,则可生成文件result1.ps 。postscript()函数中horizotal参数指定是否将图旋转90度使得x轴平行于纸的长边,width 和height规定图的宽和高,单位是英寸。

在打开了多个图形设备后可以用dev.set()函数来选择当前设备,dev.next()和dev.prev() 分别返回下一个和上一个图形设备。比如dev.set(dev.prev())选择上一个图形设备。