R语言实战-R基础包绘图

第三章 图形初阶

3.3 图形参数

通过修改图形参数来自定义一幅图形的多个特征(字体、颜色、坐标轴、标签)

1、使用par()

个人为记忆这些函数会选择匹配下他们对应的单词,我认为这个par是单词parameter的缩写,其中文意思就是参数、参量的意思。调用该函数的格式为

par(optionname=value,optionname=name,…)

不加参数地执行par()将生成一个含有当前图形参数设置的列表。添加参数no.readonly=TRUE可以生成一个可以修改的当前图形参数列表。

举例:

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) #复制了一份当前的图形参数设置

#将默认的线条类型修改为虚线(lty=2),将默认的点符号改为了实心三角(pch=17)
par(lty=2, pch=17) 

plot(dose, drugA, type="b")# 绘制了图形
par(opar) #还原了原始设置
Rplot03

2、高级绘图函数直接提供optionname=value的键值对。

plot(dose, drugA, type="b", lty=2, pch=17)

这样做出来的图和上面一样。

注意:并不是所有的高级绘图函数都允许指定全部可能的图形参数。你需要参考每个特定绘图函数的帮助文档以确定哪些参数可以以这种方式设置。

3.3.1 符号和线条

参数 描述
pch 指定绘制点时使用的符号(piont character)(见图1)
cex 指定符号的大小。cex是一个数值,表示绘图符号相对于默认大小的缩放倍数。默认大小为1,1.5表示放大为默认值的1.5倍,0.5表示缩小为默认值的50%,等等 (chatacter extent)
lty 指定线条类型(line type)(参见图2)
lwd 指定线条宽度。lwd是以默认值的相对大小来表示的(默认值为1)。例如,lwd=2将生成一条两倍于默认宽度的线条 (line width)
图1

符号21-25,可以指定边界颜色(col=)和填充色(bg=)

图2

3.3.2 颜色

用于指定颜色的参数

参数 描述
col 默认的绘图颜色。某些函数(如lines和pie)可以接受一个含有颜色值的向量并自动循环使用。例如,如果设定col=c("red", "blue")并需要绘制三条线,则第一条线将为红色,第二条线为蓝色,第三条线又将为红色
col.axis 坐标轴刻度文字的颜色
col.lab 坐标轴标签(名称)的颜色
col.main 标题颜色
col.sub 副标题颜色
fg 图形的前景色
bg 图形的背景色

R中有一些自带的配色函数比如:rainbow()、gray()等,举例来说,rainbow(10)可以生成10种连续的“彩虹型”颜色。当然还有一些专门的配色R包,比如RColorBrewer,想学习这个R包,可以查看下我的上一个推送内容~

n <- 10
mycolor <- rainbow(n)
pie(rep(1,n), labels = mycolor, col = mycolor)

mygray <- gray(0:n/n)
pie(rep(1,n), labels = mygray, col = mygray)

注意:多阶灰度色可使用gray()函数生成。这时要通过一个元素值为0和1之间的向量来指定各颜色的灰度。gray(0:10/10)将生成10阶灰度色

Rplot04
Rplot05

3.3.3 文本属性

用于指定文本大小的参数

参数 描述
cex 表示相对于默认大小缩放倍数的数值。默认大小为1,1.5表示放大为默认值的1.5倍,0.5表示缩小为默认值的50%,等等
cex.axis 坐标轴刻度文字的缩放倍数。类似于cex
cex.lab 坐标轴标签(名称)的缩放倍数。类似于cex
cex.main 标题的缩放倍数。类似于cex
cex.sub 副标题的缩放倍数。类似于cex

用于指定字体族、字号和字样的参数

参数 描述
font 整数。用于指定绘图使用的字体样式。1=常规,2=粗体,3=斜体,4=粗斜体,5=符号字体(以Adobe符号编码表示)
font.axis 坐标轴刻度文字的字体样式
font.lab 坐标轴标签(名称)的字体样式
font.mian 标题的字体样式
font.sub 副标题的字体样式
ps 字体磅值(1磅约为1/72英寸)。文本的最终大小为 ps*cex
family 绘制文本时使用的字体族。标准的取值为serif(衬线)、sans(无衬线)和mono(等宽)
par(font.axis = 1, cex.axis = 2, font.lab =4, cex.lab = 2)
plot(dose, drugA, type = 'b', lty = 3, lwd = 3, pch = 15, cex = 2)

par(font.axis = 1, cex.axis = 2, font.lab =4, cex.lab = 1)
plot(dose, drugA, type = 'b', lty = 3, lwd = 3, pch = 15, cex = 2)
Rplot07
Rplot06

上面两个图,对比了cex.lab的作用,就是控制坐标轴名称(dose drugA)的缩放倍数。

3.3.4 图形尺寸与边界尺寸

用于控制图形尺寸和边界大小的参数

参数 描述
pin 以英寸表示的图形尺寸(宽和高)
mai 以数值向量表示的边界大小,顺序为“下、左、上、右”,单位为英寸
mar 以数值向量表示的边界大小,顺序为“下、左、上、右”,单位为英分。默认值为c(5, 4, 4, 2) + 0.1

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

除了图形参数,许多高级绘图函数(例如plot、hist、boxplot)也允许自行设定坐标轴
和文本标注选项。例如:添加了标题(main)、副标题(sub)、坐标轴标签(xlab、ylab)并指定坐标轴范围(xlim、ylim)。

plot(dose, drugA, type = 'b',
     col = 'red', lty = 2, pch = 2, lwd  = 2,
     main = 'Clinical Trials for drugA',
     sub = 'hurry',
     xlab = 'Dosage',
     ylab = 'Durg response',
     xlim = c(0,60),
     ylim = c(0,70))
Rplot08

注意:

1、再次提醒,并非所有函数都支持这些选项。请参考相应函数的帮助以了解其可以接受哪些选项。

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

3.4.1 标题

title()函数为图形添加标题和坐标轴标签,亦可指定其他图形参数(如文本大小、字体、旋转角度和颜色)。如下代码:

plot(dose, drugA, type = 'b',
     col = 'red', lty = 2, pch = 2, lwd  = 2,
     main = 'Clinical Trials for drugA',
     sub = 'hurry',
     xlab = 'Dosage',
     ylab = 'Durg response',
     xlim = c(0,60),
     ylim = c(0,70), ann = F) #注意这里虽然设置了标题等参数,但我使用ann=F移除了
title(main = 'my title',col.main = 'red',cex.main = 3,
      sub = 'my sub', col.sub = 'yellow',cex.sub = 2,
      xlab = 'xlab',ylab = 'ylab',
      col.lab = 'blue', cex.lab = 2)
Rplot09

对比以下这个图和前一张图的区别就知道title()函数的作用了~

函数title()一般被用于添加信息到一个默认标题和坐标轴标签被ann=FALSE选项吸除的图形中。

3.4.2 坐标轴

函数axis()来创建自定义的坐标轴,而非使用R中的默认坐标轴。

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

坐标轴选项

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

创建自定义坐标轴时:

1、应当先禁用高级绘图函数自动生成的坐标轴。参数axes=FALSE将禁用全部坐标轴(包括坐标轴框架线,除非你添加了参数frame.plot=TRUE)。

2、参数xaxt="n"和yaxt="n"将分别禁用X轴或Y轴(会留下框架线,只是去除了刻度)。

# 生成数据
x <- c(1:10)
y <- x
z <- 10/x

# 保存当前的图形参数设置
opar <- par(no.readonly = TRUE)

# 增加边界大小,右侧多加了6英分。
par(mar = c(5,4,4,8)+0.1)

#绘制x对y的图形
plot(x,y,type = 'o',
     pch = 21, col = 'red',
     yaxt = 'n', lty = 1, ann = FALSE) #禁用y轴+移除默认标题和标签
     
# 添加x对1/x的线
lines(x, z, type = 'b', pch = 22, col = 'blue', lty = 2)

# 在左侧绘制y轴
axis(2,at = y, labels = y, col.axis = 'red', las  = 0)

# 在右侧绘制z值的轴
axis(4, at = z, labels = round(z,3), col.axis = 'blue', las = 2, cex.axis = 0.7, tck = -0.01)

# 添加标题和文本
mtext('y=1/x', side = 4, line = 3, cex.lab = 1, las = 2, col = 'blue')
title(main = 'an example of creative axes',
      xlab = 'X values',
      ylab = 'Y=X')
par(opar)# 还原默认图形参数
Rplot10

line()语句,你可以为一幅现有图形添加新的图形元素

函数mtext()用于在图形的边界添加文本。

3.4.3 参考线

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

abline(h = yvalues, v = xvalues)

h(horizontal水平线)、v(vertical垂直线)

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

上面代码的意思是x为1、3、5、7、9的位置添加了垂直的宽度为默认3倍的蓝色虚线

3.4.4 图例

legend()函数,格式如下

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

图例选项

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

书上有一幅图,我还原了下

library(Hmisc) # 这个包是添加次要刻度线的包。

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)

plot(dose, drugA,type = 'b', pch = 15, lty = 1,
     xlim = c(20,60), xlab = 'Drug Dosage',
     ylim = c(0, 60), ylab = "Drug Response")
lines(dose, drugB, type = 'b',pch = 17, lty = 2)
abline(h = c(30), lty = 3)
title(main = 'Drug A vs. Drug B')
# minor.tick函数是Hmisc包的函数,nx和ny分别指定x和y轴每两条主刻度线之间通过次刻度# 线划分得到的区间数;tick.ratio代表次要刻度线相对于主刻度线的大小比例。
minor.tick(nx = 3, ny = 3, tick.ratio = 0.5) 
legend(x = 20,y = 60, title = 'Drug Type', legend = c('A','B'), 
       pch = c(15, 17), lty = c(1, 2))

par(opar)
Rplot11

这次我们用关键词"topleft"来决定图例的位置

plot(dose, drugA,type = 'b', pch = 15, lty = 1,
     xlim = c(20,60), xlab = 'Drug Dosage',
     ylim = c(0, 60), ylab = "Drug Response")
lines(dose, drugB, type = 'b',pch = 17, lty = 2)
abline(h = c(30), lty = 3)
title(main = 'Drug A vs. Drug B')
minor.tick(nx = 3, ny = 3, tick.ratio = 0.5)
legend('topleft', inset = 0.5,title = 'Drug Type', legend = c('A','B'), 
       pch = c(15, 17), lty = c(1, 2))
Rplot12

我们可以发现参数inset=的含义是图例的左上角坐标向图形内部移动的大小。=0.5代表移到图形内部正中。

3.4.5 文本标注

text()向绘图区域内部添加文本

mtext()向图形的四个边界之一添加文本

text(location, labels = 'text to place', pos, ...)
mtext('text to place', side, line = n, ...)

函数text()和mtext()的选项

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

其他常用选项:cex、col、font分别用来调整字号、颜色和字体样式。

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

with(mtcars,{
    plot(wt, mpg,
         pch = 18,
         xlab = "Weight",
         ylab = "Mileage",
         main = "Mileage vs. Car Weight")
    text(wt, mpg,  #一系列的xy坐标轴
         labels = row.names(mtcars), # 放置的文本内容(以向量形式)
         pos = 4, #放置的文本相对于位置参数的方位,4表示右。
         offset = 1, #指定了方位后该参数表示偏移量,=1代表偏移1个字符宽度
         cex = 0.6, #设置字体相对默认值缩放倍数
         col = 'red')#设置字体颜色
    mtext('边界放置文字', #想在边界加的文字
          side = 4, #指定哪个边界(1下,2左,3上,4右)
          line = 1) #添加的文字在边线上的位置,从0开始向外数,=1代表向外数1,-1代                     #表向内数1
})
Rplot14

3.5 图形的组合

使用函数par()或layout()可以容易地组合多幅图形为一幅总括图形。

1、par()函数中使用图形参数mfrow=c(nrows, ncols)来创建按行填充、行数为nrows、列数为ncols的图形矩阵。另外,可以使用nfcol=c(nrows, ncols)按列填充矩阵。

par = par(no.readonly = TRUE)
par(mfrow = c(2,2))
with(mtcars,{
    plot(wt,mpg)
    plot(wt, disp)
    hist(wt)
    boxplot(wt)
})
par(opar)
Rplot15

2、layout()函数调用形式为layout(mat),其中的mat是一个矩阵,它指定了所要组合的
多个图形的所在位置。

layout(matrix(c(1,1,2,3),2,2,byrow = TRUE))
with(mtcars,{
    plot(wt,mpg)
    plot(wt, disp)
    hist(wt)
})
Rplot16

这个代码就是把第一幅图放于第一行,令两幅放在第二行。可以这样理解,先运行下layout里面的代码:

matrix(c(1,1,2,3),2,2,byrow = TRUE)
##       [,1] [,2]
## [1,]    1    1
## [2,]    2    3

这个数字就是我们对应的第1,2,3副图,第一行只有1,那就是放第一幅图。

3、接下来探索下,如何人为控制合并的图形中的宽与高。

layout()的两个参数:widths=和heights=

  • widths = 各列宽度值组成的一个向量
  • heights = 各行高度值组成的一个向量

Tips:相对宽度可以直接通过数值指定,绝对宽度(以厘米为单位)可以通过函数lcm()来指定

练习:将一幅图形置于第1行,两幅图形置于第2行。但第1行中图形的高度是第2行中图形高度的三分之一。除此之外,右下角图形的宽度是左下角图形宽度的四分之一:

layout(matrix(c(1,1,2,3),2,2,byrow = TRUE),
       heights = c(1,2),  # 设置上下高度比为1:2
       widths = c(3,1))   # 设置左右宽度比为3:1
with(mtcars,{
    plot(wt,mpg)
    plot(wt, disp)
    hist(wt)
})
Rplot17

图形布局的精细控制

精细控制需要用到函数par()中的参数fig=

练习:在散点图上添加两幅箱线图。

opar = par(no.readonly = T)
#画散点图
par(fig = c(0,0.8,0,0.8))
plot(mtcars$wt, mtcars$mpg,
     xlab = "wt",
     ylab = 'mpg')
     
#向右侧加箱线图
par(fig = c(0.7,1,0,0.8),new = TRUE)
boxplot(mtcars$mpg, axes = FALSE)

#向上方加箱线图
par(fig = c(0,0.8,0.5,1),new = TRUE)
boxplot(mtcars$wt, horizontal = TRUE, axes = FALSE)

#添加标题
mtext("生信知识笔记", 
      side = 3,  #指定文字添加在上方
      cex = 2,    #文字大小是默认的2倍
      line = -2)  #与边界的距离向内数2
par(opar)
Rplot18

理解这幅图需要理解绘图区域:试想完整的绘图区域:左下角坐标为(0,0),而右上角坐标为(1,1)。下图是一幅示意图。参数fig=的取值是一个形如c(x1, x2, y1, y2)的数值向量。

2

第一个fig=将散点图设定为占据横向范围00.8,纵向范围00.8。上方的箱线图横向占据00.8,纵向0.51。右侧的箱线图横向占据0.71,纵向00.8。fig=默认会新建一幅图形,所以在添加一幅图到一幅现有图形上时,请设定参数new=TRUE。

我将参数选择为0.5而不是0.8,这样上方的图形就不会和散点图拉得太远。类似地,我选择了参数0.7以拉近右侧箱线图和散点图的距离。你需要不断尝试找到合适的位置参数。尝试过程中有可能会报错“Error in plot.new(): figure margins too large”。多试几次。

小结

1、掌握par(mfrow=c(nrows, ncols))、layout(mat, heights = vector, widths = vector)、par(fig=c(x1,x2,y1,y2))这些参数的应用

2、基础的绘图包理解就好,现在画图大多都用ggplot2

参考资料:R语言实战第2版

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容