一,布局
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; |
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不规则布局0
那么参数中的widths和heights又是做什么用的呢?它们就是用来指定每行或者每列的宽度和高度的。我们可以做以下的比较:
> attach(mtcars) |
layout不规则布局1
我们发现,这两种方法得到的是相同的结果,在代码的书写上,第2种方法要更清晰一些。
想象一下,似乎每个图的位置必须是连在一起的小矩阵,如果,不构成连在一起小矩阵,会成为怎么样的一个结果呢?
> attach(mtcars) |
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) |
par实现内嵌图
二,颜色
计算机保存及还原颜色时有多种方案,较为常用的是两个,RGB和HSV。R预设了657种颜色,可以通过colors()函数调用(或者英式拼写colours())。比如我们常用的红,绿,蓝,
> colors()[c(552,254,26)] |
我们可以使用grep来调取我们感兴趣的颜色,
> grep("red",colors()) |
R颜色表
对于大多数理工出身的人来讲,理解颜色并不难,难的是如何选择一种或者多种理想的颜色,让绘图很漂亮。R当中有一个包RColorBrewer就可以为我们解决这个难题,其中预设了很多种颜色组合以供我们使用。
> library(RColorBrewer) |
RColorBrewer中预设的颜色表
我们看到其中Set3和Paired设定了12种颜色,其余的有多有少,以9种居多。在使用其颜色时,使用brewer.pal(n, name)调用即可,其中n最小值为3最大值为每组预设值数组的长度。比如brewer.pal(12,Paired)
在绘图时,有如下颜色参数
参数 | 描述 |
col | 绘图使用的颜色,许多函数接受一组颜色,并对不同的数据依次使用颜色。 |
col.axis | 坐标轴字符颜色 |
col.lab | x,y坐标标记颜色 |
col.main | 标题颜色 |
col.sub | 副标题颜色 |
fg | 绘图前景色,包括坐标轴,各类boxes |
bg | 绘图背景色 |
> require(graphics) |
颜色设置示例
三,字体
字体参数如下:
参数 | 描述 |
font | 字体描述,1正常,2加粗,3斜体,4加粗,斜体,5符号 |
font.axis | 坐标轴字符描述 |
font.lab | 坐标轴标记字体描述 |
font.main | 标题字体描述 |
font.sub | 副标题字体描述 |
ps | 字体点阵大小,大约为1/72英寸。在使用时text size=ps*cex |
cex | 字体放大或者缩小多少倍 |
cex.axis | 坐标轴字符大小 |
cex.lab | 坐标轴标记字体大小 |
cex.main | 标题字体大小 |
cex.sub | 副标题字体大小 |
family | 绘图字体。标准字体是”serif”,”sans”,”mono”,”symbol”。当然可以指定任何自己已有的字体库。但它是设备依赖的。 |
> fonts<-names(pdfFonts()) |
字体
四,符号与线形
画图中的符号由pch参数来控制。其描边色由col控制,填充色由bg控制。
> pchShow <- |
符号
线形主要由lty和lwd来控制。lty: line type. lwd: line width.顾名思意,lty控制线的形状,而lwd控制线的粗细,默认值为1。设计成2表示两倍线宽。
线形
五,坐标轴,图例,标记与标题
相关参数来控制,它们有
参数 | 描述 |
main | 主标题 |
sub | 副标题 |
xlab | x轴标记 |
ylab | y轴标记 |
xlim | x轴上下限(范围) |
ylim | y轴上下限 |
mgp | 坐标轴标记,坐标字符,坐标刻度线距离坐标轴的行数,默认值为c(3,1,0) |
增加一个新的坐标轴使用axis()函数。
参数 | 描述 |
side | 坐标轴所在的位置,1:下,2:左,3:上,4:右 |
at | 坐标轴具体位置,通常由自动给出。 |
labels | 坐标字符串 |
pos | 坐标轴线所在的行,默认值为重绘所在位置上的原坐标 |
lty | 线型 |
col | 颜色 |
las | 坐标标记与坐标轴方位关系,=0为平等,=2为垂直 |
lwd.ticks | 坐标刻度线宽度 |
col.ticks | 坐标刻度线颜色 |
(…) | 其它par()中可用的参数 |
> # A Silly Axis Example |
坐标轴
图例使用legend()函数控制
参数 | 描述 |
x,y | 图例所在位置,可以使用”bottom”,”bottomleft”,”left”,”topleft”,”top”,”topright”,”right”,”bottomleft”,”center”来指定。 |
inset | 设置在主绘图边距 |
title | 图例的标题 |
legend | 图例的内容 |
… | 其它par()可用的参数 |
> attach(mtcars) |
图例
文本框使用text或者mtext函数。text可以在主绘图区内加文本框,mtext在边距或者外边距上加文本框。
text(location, “text to place”, pos, …)
mtext(“text to place”, side, line=n, …)
参数 | 描述 |
location | 图例所在位置 |
pos | 所在的相对位置,1:下面,2:左边,3:上面,4:右边 |
side | 所在边距的位置,1:下,2:左,3:上,4:右 |
… | 其它par()可用的参数 |
> attach(mtcars) |
文本框
六,各类图型
点,线,面
点:points,线:abline,lines,segments,面:box,polygon,polypath,rect,特殊的:arrows,symbols
points不仅仅可以画前文中pch所设定的任意一个符号,还可以以字符为符号。
> ## ------------ test code for various pch specifications ------------- |
画点
abline可以由斜率和截距来确定一条直线,lines可以连接两个或者多个点,segments可以按起止位置画线。
> require(stats) |
线段
box画出当前盒子的边界,polygon画多边形,polypath画路径,rect画距形。
> x <- c(1:9,8:1) |
多边形
路径
矩形
arrows用于画箭头,symbols用于画符号
> ## Note that example(trees) shows more sensible plots! |
符号
画圆
> library(plotrix) |
圆
散点图及趋势线
一维点图使用dotchart函数。
> # Dotplot: Grouped Sorted and Colored |
一维点图
二维散点图使用plot函数。直趋势线使用abline函数,拟合曲线在拟合后使用line函数绘制。
> attach(mtcars) |
点阵图
曲线
曲线使用lines函数。其type参数可以使用”p”,”l”,”o”,”b,c”,”s,S”,”h”,”n”等。
> x <- c(1:5); y <- x # create some data |
曲线
柱状图
普通的柱状图使用barplot函数。其参数horiz=TRUE表示水平画图,beside=TRUE表示如果是多组数据的话,在并排画图,否则原位堆叠画图。
> par(mfrow=c(1,2)) |
bar图
柱状统计图使用hist函数。其breaks参数设置每组的范围。使用density函数可以拟合曲线。
> hist(mtcars$mpg, breaks=12) |
柱状图
饼图
饼图使用pie函数。
> x<-table(mtcars$gear) |
饼图
3维饼图使用plotrix库中的pie3D函数。
> x<-table(mtcars$gear) |
3D饼图
箱线图
箱线图使用boxplot函数。boxplot中参数x为公式。R中的公式如何定义呢?最简单的 y ~ x 就是y是x的一次函数。好了,下面就是相关的符号代表的意思:
符号 | 示例 | 意义 |
+ | +x | 包括该变量 |
– | -x | 不包括该变量 |
: | x:z | 包括两变量的相互关系 |
* | x*z | 包括两变量,以及它们之间的相互关系 |
/ | x/z | nesting: include z nested within x |
| | x|z | 条件或分组:包括指定z的x |
^ | (u+v+w)^3 | include these variables and all interactions up to three way |
poly | poly(x,3) | polynomial regression: orthogonal polynomials |
Error | Error(a/b) | specify the error term |
I | I(x*z) | as is: include a new variable consisting of these variables multiplied |
1 | -1 | 截距:减去该截距 |
> boxplot(mpg~cyl,data=mtcars, main="Car Milage Data", |
箱线图
如果我想在箱线图上叠加样品点,即所谓的蜂群图,如何做呢?
> source("http://bioconductor.org/biocLite.R") |
蜂群图
> require(beeswarm) |
蜂群图
分枝树
> require(graphics) |
分枝树
文氏图
> library(limma) |
文氏图
七,综合应用
点阵图加两方向柱状图
> def.par <- par(no.readonly = TRUE) # save default, for resetting... |
点阵+柱状
带误差的点线图
> # Clustered Error Bar for Groups of Cases. |
误差图
误差绘图plotCI加强版是plotmeans,具体可使用?plotmeans来试用它。这里就不多讲了。
带误差的柱状图。还是使用gplots包
> library(gplots) |
带误差的柱状图
漂亮的箱线图
> require(gplots) #for smartlegend |
箱线图
基因芯片热图,具体参考http://www2.warwick.ac.uk/fac/sci/moac/students/peter_cock/r/heatmap/
> library("ALL") |
点柱图(dothistogram)
英文名称 | 中文名称 |
bar | 条形图 |
line | 线图 |
area | 面积图 |
pie | 饼图 |
high-low | 高低图 |
pareto | 帕累托图 |
control | 控制图 |
boxplot | 箱线图 |
error bar | 误差条图 |
scatter | 散点图 |
P-P | P-P正态概率图 |
Q-Q | Q-Q正态概率图 |
sequence | 序列图 |
ROC Curve | ROC分类效果曲线图 |
Time Series | 时间序列图 |
好了,言归正传。那么什么又是点柱图(dot histogram)呢?之前我又称之为蜂群图(beeswarm)。还有称之为抖点图(jitter plots)。总之无论如何,在糗世界里我都称之为点柱图吧。
我们先看点柱图效果:
点柱图
以下是代码
> require(beeswarm) |
以下是解释
在很多情况下,我们画散点图的时候,有许多点拥有相同的横坐标,如果我们简单的使用plot(x,y)的方式,会显得这些点拥挤在一起,象图中左上角一样,非常的不舒服。我们需要把这些点分散开。
最基本的思路是,把横坐标抖散(jitter),使本来都拥有相同坐标的点的横坐标稍有不同。jitter是基类函数{base},无需调用任何包。
> plot(jitter(breast$event_survival), breast$time_survival, main="Using Jitter on x-axis",col=as.numeric(breast$ER),xaxt="n",xlim=c(-0.5,1.5)) |
我们比较图中上边靠右的两个图,我们发现,如果只抖散x坐标的话,还是有些点会粘在一起,所以同时抖散y坐标会好一些。我们可以使用factor参数来控制jitter抖散的强度。
> plot(rep(c(1,5,10),each=5),c(jitter(rep(100,5),factor=1),jitter(rep(100,5),factor=5),jitter(rep(100,5),factor=10)),col=c("red","blue","green","gray","black"),xlim=c(-2,13),xlab="",ylab="y",xaxt="n",main="jitter(rep(100,5)) with different factor") |
不同强度的jitter
在graphics包中提供了一个sunflowerplot的函数。它的目的是用花瓣数目多少来显示落在同一坐标上的点的数目。但是从中左图看来,点多的时候效果并非总是那么好。
在plotrix包中提供了一些有意思的函数来解决点挤在一起的这个问题,它们分别是cluster.overplot, count.overplot, sizeplot。这三个函数的效果如图中及下靠左的两个。cluster.overplot的方法类似抖散,count overplot的方法是使用数字来显示落在同一坐标上的点的数目,sizeplot的方法是使用不同大小是点来显示落在同一坐标上的点的数目。从效果来看,点多的时候效果也并非理想。
而上一次提到过的蜂群图似乎是解决这一问题的最佳方案。
我们得出结论,在点数不同的情况下,使用plotrix包及sunflowerplot是不错的。但点数较多的情况下,还是使用jitter和beeswarm较为稳妥。
我们也可以使用ggplot2包中的geom来绘制点柱图
> require(beeswarm) |
ggplot点柱图
还有一种图,名称为Engelmann-Hecker-Plot, 由plotrix的ehplot来实现。
> data(iris);library(plotrix) |
坐标中断(axis breaks)
R当中的坐标中断一般都使用plotrix库中的axis.break(), gap.plot(), gap.barplot(), gap.boxplot()等几个函数来实现,例:
gap plot
> library(plotrix) |
从图像效果上来看,这样的坐标中断只能说实现了坐标中断,但效果上是非常一般的。甚至远不如excel, openoffice当中出图效果好。为此,我们需要对plotrix库中的gap.plot做出修改,以达到满意的效果。
最简单的修改办法就是在使用了gap.plot, gap.barplot, gap.boxplot之后重新使用axis.break来修改中断类型,使得看上去美一点。
> axis.break(2,from,breakcol="snow",style="gap") |
使用上面的办法可以绘制出双反斜线中断,并可以视实际情况加油断点起止位置。
改进的gap.plot
> library(plotrix) |
来源:http://blog.qiubio.com:8080/rbioconductor-2