R绘图基础(1)布局

评论6,410

R绘图所占的区域,被分成两大部分,一是外围边距,一是绘图区域。

外围边距可使用par()函数中的oma来进行设置。比如oma=c(4,3,2,1),就是指外围边距分别为下边距:4行,左边距3行,上边距2行,右边距1行。很明显这个设置顺序是从x轴开始顺时针方向。这里的行是指可以显示1行普通字体。所以当我们使用mtext中的line参数时,设置的大小就应该是[0,行数)的开区间。当我们使用mtext在外围边距上书写内容时,设置mtext中的outer=TRUE即可。

绘图区域可使用par()函数中的mfrow, mfcol来进行布局。mfrow和mfcol可以使用绘图区域被区分为多个区域。默认值为mfrow(1,1)。

比如mfrow(2,3)就是指将绘图区域分成2行3列,并按行的顺序依次绘图填充;
比如mfcol(3,2)就是指将绘图区域分成3行2列,并按列的顺序依次绘图填充;

我们将每一个细分的绘图区域分为两个部分,一是绘图边距,一是主绘图。

绘图边距需要容纳的内容有坐标轴,坐标轴标签,标题。通常来讲,我们都只需要一个x轴,一个y轴,所以在设置时,一般的下边距和左边距都会大一些。如果多个x轴或者y轴,才考虑将上边距或者右边距放大一些。绘图边距可以使用par()函数中mar来设置。比如mar=c(4,3,2,1),与外围边距的设置类似,是指绘图边距分别为下边距:4行,左边距3行,上边距2行,右边距1行。很明显这个设置顺序是从x轴开始顺时针方向。行的概念与之前的相同。也可以使用mai来设置。mai与mar唯一不同之处在于mai不是以行为单位,而是以inch为单位。

SOUTH<-1; WEST<-2; NORTH<-3; EAST<-4;
 
GenericFigure <- function(ID, size1, size2)
{
  plot(0:10, 0:10, type="n", xlab="X", ylab="Y")
  text(5,5, ID, col="red", cex=size1)
  box("plot", col="red")
  mtext(paste("cex",size2,sep=""), SOUTH, line=3, adj=1.0, cex=size2, col="blue")
  title(paste("title",ID,sep=""))
}
 
MultipleFigures <- function()
{
  GenericFigure("1", 3, 0.5)
  box("figure", lty="dotted", col="blue")
 
  GenericFigure("2", 3, 1)
  box("figure", lty="dotted", col="blue")
 
  GenericFigure("3", 3, 1.5)
  box("figure", lty="dotted", col="blue")
 
  GenericFigure("4", 3, 2)
  box("figure", lty="dotted", col="blue")
}
 
par(mfrow=c(2,2),mar=c(6,4,2,1),oma=c(4,3,2,1))
 
MultipleFigures()
 
box("inner", lty="dotted", col="green")
box("outer", lty="solid", col="green")
 
mtext("Outer Margin Area (oma) of South: 6", SOUTH, line=1, cex=1, outer=TRUE)
 
plotline<-function(n,direc){
  for(i in 0:n){
    mtext(paste("line",i,sep=""), direc, line=i, cex=1, col="black", adj=1, outer=TRUE)
  }
}
plotline(4,SOUTH)

R绘图基础(1)布局-图片1

R绘图布局

但是,使用mfrow,mfcol只能是矩阵似的布局,如果我们需要简单地实际不规则的布局,那该怎么办呢?还有强大的layout()专门用于布局。

layout(mat, widths = rep(1, ncol(mat)), heights = rep(1,nrow(mat)),respect = FALSE)

其中,mat就是一个距阵,假设我们要画N个图,那么,mat就要描述每个图所在的位置,其中1…N-1都必须至少出现过一次。比如有三个图,我们希望的布局是第一排有一个图,第二排有两个图,那么mat<-matrix(c(1,1,2,3), nrow=2, ncol=2, byrow = TRUE);如果希望第一排有两个图,第二排有一个图,那么就是mat<-matrix(c(1,2,3,3),nrow=2,ncol=2,byrow=TRUE)。很明显,还是将画布分成许多小格矩阵,这里就是2X2的,如果希望第1个图放入第一排的1,2格,那就在矩阵的第1,2的位置写入1,如果是希望第2个图放在第一排的1,2格,那就在矩阵的第1,2的位置写入2。

> attach(mtcars)
> layout(matrix(c(1,1,2,3), 2, 2, byrow = TRUE))
> hist(wt)
> hist(mpg)
> hist(disp)

R绘图基础(1)布局-图片2

layout不规则布局0

那么参数中的widths和heights又是做什么用的呢?它们就是用来指定每行或者每列的宽度和高度的。我们可以做以下的比较:

> attach(mtcars)
> layout(matrix(c(1,1,1,1,2,2,2,3,2,2,2,3),3,4,byrow=TRUE))
> hist(wt)
> hist(mpg)
> hist(disp)
> 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)

R绘图基础(1)布局-图片3

layout不规则布局1

我们发现,这两种方法得到的是相同的结果,在代码的书写上,第2种方法要更清晰一些。

想象一下,似乎每个图的位置必须是连在一起的小矩阵,如果,不构成连在一起小矩阵,会成为怎么样的一个结果呢?

> attach(mtcars)
> layout(matrix(c(1,1,2,1,1,1),nrow=2,ncol=3,byrow=T))
> hist(wt)
> hist(mpg)

R绘图基础(1)布局-图片4

layout内嵌图布局

如果需要大图,小图,内嵌图这layout()虽然很容易实现,但多少有点麻烦,不是那么随心所欲。还是回过头来使用par()吧。使用par()的中fig=在画布任意位置上画图。在使用fig参数时,需要把画布理解成左下角为坐标(0,0),右上角为(1,1)的一个坐标系。fig=c(x1,x2,y1,y2)来设置该参,x1<x2,y1<y2,x1,y1定位绘图区的左下角,x2,y2定位绘图区的右上角。使用new=TRUE参数来确认是否在原画布上继续画,还重新在一张新画布上开始画。

> par(fig=c(0,0.85,0,0.85), new=F)
> 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(fig=c(0.4,0.75,0.4,0.7),new=TRUE,mar=c(2,2,0,0),mgp=c(1,.4,0),cex=1,cex.lab=0.7,cex.axis=0.7)
> hist(mtcars$mpg, main="")

R绘图基础(1)布局-图片5

par实现内嵌图

 

发表评论

匿名网友