前言

千呼万唤始出来,终于到了图形这部分,这部分主要说明如何创建和保存图形以及图形相关常用的参数使用。

图形相关基础函数

使用图形

首先,先在你的R上运行如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
# 创建一个 1.jpg 的文件
jpeg('1.jpg')
# 绑定trees数据
attach(trees)
# 根据Height和Volume绘制点图形
plot(Height,Volume)
# 自定义图形标题
title("这是一个标题")
# 解除绑定trees数据
detach(trees)
# 返回输出结果
dev.off()

运行后会在当前工作目录下产生一个名称为1.jpg的图片,如下所示:

image-20220507194124730

这就是所生成的图形,利用的是trees数据所生成的图形。

图形输出

用于图形输出的函数如下所示:

函数 功能
pdf('filename.pdf') 输出PDF文件
png('filename.png') 输出PNG文件
jpeg('filename.jpg/jpeg') 输出JPG文件
bmp('filename.bmp') 输出BMP文件

需要注意的是使用上述函数输出图片后要使用dev.off()函数来完成文件输出

关于JPGJPEG的区别可以参考我这篇文章琐碎问题记录

图形参数

我们可以通过修改图形的相关参数来实现我们想要的图形效果,例如图形颜色,图形样式等。

修改图形参数的方式有两种,第一种是使用par()函数来修改全局参数,第二种是在定义图形的时候定义相关参数。关于par()函数的使用后续说明。

在前面的代码中,以及试验过了plot()函数的输出结果,即图形样式。函数原型如下:

1
2
3
4
5
6
plot(x, y = NULL, type = "p",  xlim = NULL, ylim = NULL,
log = "", main = NULL, sub = NULL, xlab = NULL, ylab = NULL,
ann = par("ann"), axes = TRUE, frame.plot = axes,
panel.first = NULL, panel.last = NULL, asp = NA,
xgap.axis = NA, ygap.axis = NA,
...)
  • **x**:即x轴数据
  • **y**:即y轴数据

符号和线条

可以通过设置以下参数来修改图形的符号和线条类型:

参数 说明
pch 指定绘制点时使用的符号
cex 指定符号的大小。cex是数值型,默认大小为1,2表示放大2倍
lty 指定线条类型
lwd 指定线条宽度。默认值为1,同cex

关于**pch值对应的点符号样式**如下图:

image-20220507202152075

关于lty参数对应线条的类型样式如下图:

image-20220507202632041

颜色

用于颜色指定的相关参数如下:

参数 说明
col 设置绘图颜色。某些函数可以接受颜色值向量并自动循环使用。例如:col=c('red','green)则绘制的图线先红色后绿色,周而复始.
col.axis 坐标轴刻度文字的颜色
col.lab 坐标轴标签的颜色
col.main 标题颜色
col.sub 副标题颜色
fg 前景色(即图表框的颜色)
bg 背景色

颜色的指定可以通过颜色索引,颜色名称,十六进制颜色值,RGB值或者HSV值来指定颜色。例如:

1
2
3
4
5
col=1
col='white'
col='#FFFFFF'
col=rgb(1,1,1)
col=hsv(0,0,1)

文本属性

图形参数同样可以用来指定字号,字体和字样等,参数如下所示:

参数 说明
cex 表示绘图大小,默认为1
cex.axis 坐标轴刻度字体的大小,大小设置同上
cex.lab 坐标轴标签的大小,大小设置同上
cex.main 标题的大小,大小设置同上
cex.sub 副标题的大小,大小设置同上
————- ————————————–
font 接收整型参数,用于指定绘图字体样式。(1=常规,2=粗体,3=斜体,4=粗斜体,5=符号字体)
font.axis 坐标轴刻度字体样式,同上
font.lab 坐标轴标签字体样式,同上
font.main 标题字体样式,同上
font.sub 副标题字体样式,同上
ps 字体磅值(1磅 $\approx$ $\frac{1}{72}$ 英寸),文本最终大小=$ps \times cex$
family 绘制文本时使用的字体族。

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

图形尺寸于边界尺寸

同样的可以通过参数来控制生成图形的尺寸,如下所示:

参数 说明
pin 以英寸表示图形的尺寸(宽和高)
mai 以数值向量表示边界的大小,顺序是下,左,上,右,单位为英寸
mar 以数值向量表示边界大小,顺序同上,单位是英分

1英寸=2.54厘米,1英分= $\frac{1}{12}$ 英寸

标题

需要高级绘图函数(例如plothistboxplot)允许设定更多的自定义内容,例如标题,图例等。

某些高级绘图函数默认包含了标题和标签,可以通过设置ann=FLASE来移除它们

可以使用title()函数为图形添加标题和坐标轴标签,函数原型如下:

1
2
title(main = NULL, sub = NULL, xlab = NULL, ylab = NULL,
line = NA, outer = FALSE, ...)

NA是Not Available的缩写,是一种占位符,可以理解为值=NA,但是不存在

代码示例:

1
title(main = '这是主标题',sub = '这是副标题',xlab = '这是横坐标标签',ylab = '这是纵坐标标签')

坐标轴

可以使用函数axis()来创建自定义坐标轴。函数原型如下:

1
2
3
4
axis(side, at = NULL, labels = TRUE, tick = TRUE, line = NA,
pos = NA, outer = FALSE, font = NA, lty = "solid",
lwd = 1, lwd.ticks = lwd, col = NULL, col.ticks = NULL,
hadj = NA, padj = NA, gap.axis = NA, ...)

参数说明如下:

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

创建自定义坐标轴时,应该禁用高级绘图函数自动生成的坐标轴。

  • 参数axes=FLASE将禁用全部坐标轴(包括坐标轴框架线)
  • 参数xaxt='n'yaxt='n'将分别禁用 X 轴或者 Y 轴(会留下框架线,只是去除了刻度)

现在运行如下代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 定义数据
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)

# 绘制左侧Y轴刻度线
axis(2,at=x,labels = x,col.axis='red',las=2)

# 绘制右侧Y轴刻度线
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('这是一个样图',xlab = '这是横坐标',ylab = '这是纵坐标',line = 2)

par(opar)

运行结果生成的图形如下:

image-20220508105802075

关于上述语法解释,**line()函数是绘制图线**,其函数原型如下:

1
line(x, y, iter = 1)

其中参数type的值以及功能如下:

参数 功能
type='p' 表示绘制点
type='l' 表示绘制线
type='b' 表示绘制点和线
type='c' 表示曲线连接的空点
type='s'或者type='S' 表示阶梯状线
type='h' 表示直方图状垂直线
type='n' 表示不产生任何点或者线

round()函数是进行四舍五入的函数,函数原型如下:

1
round(x, digits = 0)
  • x:需要处理的数据
  • digits:要使用的小数位数或者有效数字的数目

mtext函数是将文本写在图形区域的是个边距的周围。函数原型如下:

1
2
mtext(text, side = 3, line = 0, outer = FALSE, at = NA,
adj = NA, padj = NA, cex = NA, col = NA, font = NA, ...)

相关参数说明如下:

参数 说明
text 标题内容
side 文本在坐标轴边框的位置(1=下,2=左,3=上,4=右)
line 距离坐标轴边框的距离,值越大越远
las 文字是否平行(=0)或者垂直于(=2)坐标轴

次要刻度线

如上创建的图形都只拥有主刻度线,没有次刻度线。想要创建次刻度线,需要使用Hmisc宏包的minor.tick()函数。minor.tick()函数原型如下:

1
minor.tick(nx=2, ny=2, tick.ratio=0.5, x.args = list(), y.args = list())
  • nx:指在X轴分割的区域,2即次刻度线将每个区间分为两个区域
  • ny:指在Y轴分割的区域,同上
  • tick.ratio:表示次刻度相对于主刻度线的大小比例

参考线

函数abline()可以用来为图形添加参考线,函数原型如下:

1
2
abline(a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
coef = NULL, untf = FALSE, ...)
  • h:Y 轴的参考线
  • v:X 轴的参考线

代码实例:

1
2
# 在垂直 3 坐标和水平 2 坐标,用虚线话画出红色的参考线
abline(h=2,v=3,lty=2,col='red')

图例

当图形中存在多个数据的时候,使用图例可以帮助读者快速区分数据曲线。

可以使用函数legend()来添加图例。函数原型如下:

1
2
3
4
5
6
7
8
9
10
11
12
legend(x, y = NULL, legend, fill = NULL, col = par("col"),
border = "black", lty, lwd, pch,
angle = 45, density = NULL, bty = "o", bg = par("bg"),
box.lwd = par("lwd"), box.lty = par("lty"), box.col = par("fg"),
pt.bg = NA, cex = 1, pt.cex = cex, pt.lwd = lwd,
xjust = 0, yjust = 1, x.intersp = 1, y.intersp = 1,
adj = c(0, 0.5), text.width = NULL, text.col = par("col"),
text.font = NULL, merge = do.lines && has.pch, trace = FALSE,
plot = TRUE, ncol = 1, horiz = FALSE, title = NULL,
inset = 0, xpd, title.col = text.col[1], title.adj = 0.5,
title.cex = cex[1], title.font = text.font[1],
seg.len = 2)

参数说明如下:

参数 说明
location 有两种定位图例位置的方法,第一种是通过指定 X,Y 的值来指定图例的位置(以图例左上角为顶点),第二种方式是通过指定关键字,"bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright", "right" and "center",如果使用关键字指定位置,可以通过inset参数来调整其距离边框的位置。
title 图例的标题

代码示例:

1
legend("topleft",title = '图例标题',inset = 0.2,c('A','B'),pch=c(2,5))

效果如下:

image-20220508191935662

文本标注

可以通过函数text()mtext()将文本添加到图形,text()可以向绘图区域内添加文字,而mtext()是向绘图区域四周添加文字。函数原型如下:

1
2
3
4
5
6
# mtext
mtext(text, side = 3, line = 0, outer = FALSE, at = NA,
adj = NA, padj = NA, cex = NA, col = NA, font = NA, ...)

# text
text(x, ...)

mtext函数已经在坐标轴部分说明了,text的相关参数说明如下;

  • x:指定 X 轴的位置
  • y:指定 Y 轴的位置
  • label:标注内容
  • pos:标准内容和点的偏移量

代码示例:

1
2
3
4
5
6
7
8
9
10
11
# 创建数据
a <- c(1:10)
b <- 1/c(1:10)

# 绘制图形
plot(a,b)

# 添加坐标的文字
text(1,1,'这是第一个数据',pos=4)
text(2,1/2,'这是第二个数据',pos=4)
text(3,1/3,'这是第三个数据',pos=4)

运行效果:

image-20220508193453179

数学标注

同样的,你也可以使用类似于Tex中的写法为图形添加数学符号和公式可以利用plotmath()函数来实现,如果你希望看到即时效果,可以尝试运行demo(plotmath)来查看。

代码示例:

1
2
# 使用 expression() 来呈现数学公式
text(2,1/2,labels=expression(frac(1,2)),pos=4)

关于Tex/LaTex用法说明,可以看我这篇文章LaTex基础(上)

图形的组合

在R中使用函数par()或者layout()可以组合多幅图形为一幅总括图

可以通过par()函数中使用图形参数mfrow=c(nrows,ncols)来创建按行填充的图形矩阵,或者可以使用**nfcol=c(nrows,ncols)来按列填充矩阵**。代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 绑定数据源
attach(trees)
# 获取初始图形参数
opar <- par(no.readonly = TRUE)
# 设置两行两列
par(mfrow=c(2,2))
# 绘制图形
plot(Height,Volume,main='第一个图')
plot(Height,Girth,main='第二个图')
hist(Height,main='第三个图')
boxplot(Height,main='第四个图')
# 设置图形参数
par(opar)
# 解绑数据源
detach(trees)

运行效果如下:

image-20220509101320519

接下来尝试使用layout()函数绘制组合图形,其函数原型如下:

1
2
layout(mat, widths = rep.int(1, ncol(mat)),
heights = rep.int(1, nrow(mat)), respect = FALSE)
  • mat:矩阵类型参数,四个参数表示四个位置

代码示例:

1
2
3
4
5
6
attach(trees)
layout(matrix(c(1,1,2,3),2,2,byrow = TRUE))
hist(Height)
hist(Volume)
hist(Girth)
detach(trees)

运行效果如下:

image-20220509102709140

为了更精细的控制每幅图的大小,可以有选择性的在layout()函数中使用heightswidths两个参数

  • widthsheights:两个函数都接收一个向量参数,是一种比例

相对高度可以通过数值来指定,绝对高度通过函数lcm()来指定。代码示例:

1
2
3
4
5
6
7
attach(trees)
layout(matrix(c(1,1,2,3),2,2,byrow = TRUE)
,widths = c(3,1),heights = c(1,2))
hist(Height)
hist(Volume)
hist(Girth)
detach(trees)

运行效果如下:

image-20220509103823858

图形的精细化控制

在某些情况下,你可能希望通过多个图形叠加来形成其他图形,这个时候就需要使用fig参数来实现。代码示例如下:

1
2
3
4
5
6
7
8
attach(trees)
par(fig=c(0,0.8,0,0.8))
plot(Height,Volume)
par(fig=c(0,0.8,0.5,1),new=TRUE)
boxplot(Height,horizontal = TRUE,axes=FALSE)
par(fig=c(0.65,1,0,0.8),new=TRUE)
boxplot(Volume,axes=FALSE)
detach(trees)
  • new=TRUE:意思是绘制图形的时候不清楚原图像,而是继续叠加绘图

运行效果如下:

image-20220509105257431

**fig参数接收一个四参数的向量,它表示的是相对位置,其参数类型为fig=c(x1,x2,y1,y2)**,代码par(fig=c(0,0.8,0,0.8))的意思是规定图形的绘制范围为:横向从 0 到 0.8 这个比例范围内,纵向 0 到 0.8 这个比例范围内。

如果你在绘图过程中报错figure margins too large,则说明绘图已经超出绘图设备区域,适当缩小绘图区域即可。

End

这部分初步理解和利用图形相关参数来实现一些基本的自定义图形。