R繪圖基礎

一,佈局

R繪圖所佔的區域,被分紅兩大部分,一是外圍邊距,一是繪圖區域。git

外圍邊距可以使用par()函數中的oma來進行設置。好比oma=c(4,3,2,1),就是指外圍邊距分別爲下邊距:4行,左邊距3行,上邊距2行,右邊距1行。很明顯這個設置順序是從x軸開始順時針方向。這裏的行是指能夠顯示1行普通字體。因此當咱們使用mtext中的line參數時,設置的大小就應該是[0,行數)的開區間。當咱們使用mtext在外圍邊距上書寫內容時,設置mtext中的outer=TRUE便可。github

繪圖區域可以使用par()函數中的mfrow, mfcol來進行佈局。mfrow和mfcol可使用繪圖區域被區分爲多個區域。默認值爲mfrow(1,1)。express

好比mfrow(2,3)就是指將繪圖區域分紅2行3列,並按行的順序依次繪圖填充;
好比mfcol(3,2)就是指將繪圖區域分紅3行2列,並按列的順序依次繪圖填充;數組

咱們將每個細分的繪圖區域分爲兩個部分,一是繪圖邊距,一是主繪圖。app

繪圖邊距須要容納的內容有座標軸,座標軸標籤,標題。一般來說,咱們都只須要一個x軸,一個y軸,因此在設置時,通常的下邊距和左邊距都會大一些。若是多個x軸或者y軸,才考慮將上邊距或者右邊距放大一些。繪圖邊距可使用par()函數中mar來設置。好比mar=c(4,3,2,1),與外圍邊距的設置相似,是指繪圖邊距分別爲下邊距:4行,左邊距3行,上邊距2行,右邊距1行。很明顯這個設置順序是從x軸開始順時針方向。行的概念與以前的相同。也可使用mai來設置。mai與mar惟一不一樣之處在於mai不是以行爲單位,而是以inch爲單位。ide

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繪圖佈局函數

 

可是,使用mfrow,mfcol只能是矩陣似的佈局,若是咱們須要簡單地實際不規則的佈局,那該怎麼辦呢?還有強大的layout()專門用於佈局。佈局

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

其中,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)

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)

layout不規則佈局1

咱們發現,這兩種方法獲得的是相同的結果,在代碼的書寫上,第2種方法要更清晰一些。

想象一下,彷佛每一個圖的位置必須是連在一塊兒的小矩陣,若是,不構成連在一塊兒小矩陣,會成爲怎麼樣的一個結果呢?

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

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="")

par實現內嵌圖

二,顏色

計算機保存及還原顏色時有多種方案,較爲經常使用的是兩個,RGB和HSV。R預設了657種顏色,能夠經過colors()函數調用(或者英式拼寫colours())。好比咱們經常使用的紅,綠,藍,

> colors()[c(552,254,26)]
[1] "red"   "green" "blue"

咱們可使用grep來調取咱們感興趣的顏色,

> grep("red",colors())
[1] 100 372 373 374 375 376 476 503 504 505 506 507 524 525 526 527 528 552 553
[20] 554 555 556 641 642 643 644 645
 
> colors()[grep("red",colors())]
[1] "darkred" "indianred" "indianred1" "indianred2" 
[5] "indianred3" "indianred4" "mediumvioletred" "orangered" 
[9] "orangered1" "orangered2" "orangered3" "orangered4" 
[13] "palevioletred" "palevioletred1" "palevioletred2" "palevioletred3" 
[17] "palevioletred4" "red" "red1" "red2" 
[21] "red3" "red4" "violetred" "violetred1" 
[25] "violetred2" "violetred3" "violetred4"
 
> colors()[grep("sky",colors())]
[1] "deepskyblue" "deepskyblue1" "deepskyblue2" "deepskyblue3" 
[5] "deepskyblue4" "lightskyblue" "lightskyblue1" "lightskyblue2"
[9] "lightskyblue3" "lightskyblue4" "skyblue" "skyblue1" 
[13] "skyblue2" "skyblue3" "skyblue4"
 
> SetTextContrastColor <- function(color)
+ {
+   ifelse( mean(col2rgb(color)) > 127, "black", "white")
+ }
> # Define this array of text contrast colors that correponds to each
> # member of the colors() array.
> TextContrastColor <- unlist( lapply(colors(), SetTextContrastColor) )
 
> # 1a. Plot matrix of R colors, in index order, 25 per row.
> # This example plots each row of rectangles one at a time.
> colCount <- 25 # number per row
> rowCount <- 27
> plot( c(1,colCount), c(0,rowCount), type="n", ylab="", xlab="",
+   axes=FALSE, ylim=c(rowCount,0))
> title("R colors")
> 
> for (j in 0:(rowCount-1))
+ {
+   base <- j*colCount
+   remaining <- length(colors()) - base
+   RowSize <- ifelse(remaining < colCount, remaining, colCount)
+   rect((1:RowSize)-0.5,j-0.5, (1:RowSize)+0.5,j+0.5,
+     border="black",
+     col=colors()[base + (1:RowSize)])
+   text((1:RowSize), j, paste(base + (1:RowSize)), cex=0.7,
+     col=TextContrastColor[base + (1:RowSize)])
+ }

R顏色表

對於大多數理工出身的人來說,理解顏色並不難,難的是如何選擇一種或者多種理想的顏色,讓繪圖很漂亮。R當中有一個包RColorBrewer就能夠爲咱們解決這個難題,其中預設了不少種顏色組合以供咱們使用。

> library(RColorBrewer)
> display.brewer.all()

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)
> par(col.axis="green",col.lab="blue",col.main="darkred",fg="white",bg="black")
> plot(cars,main="speed vs dist")

顏色設置示例

三,字體

字體參數以下:

參數 描述
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())
> cnt<-length(fonts)
> x<-cnt+10
> x<-1:x
> y<-x
> pdf("font.pdf")
> plot(x,y,type="n")
> for(i in 1:cnt){text(i,i*1.3,family=fonts[i],paste("font",fonts[i]),adj=0)}
> dev.off()

字體

四,符號與線形

畫圖中的符號由pch參數來控制。其描邊色由col控制,填充色由bg控制。

> pchShow <-
+   function(extras = c("*",".", "o","O","0","+","-","|","%","#"),
+            cex = 3, ## good for both .Device=="postscript" and "x11"
+            col = "red3", bg = "gold", coltext = "brown", cextext = 1.2,
+            main = paste("plot symbols :  points (...  pch = *, cex =",
+                         cex,")"))
+   {
+     nex <- length(extras)
+     np  <- 26 + nex
+     ipch <- 0:(np-1)
+     k <- floor(sqrt(np))
+     dd <- c(-1,1)/2
+     rx <- dd + range(ix <- ipch %/% k)
+     ry <- dd + range(iy <- 3 + (k-1)- ipch %% k)
+     pch <- as.list(ipch) # list with integers & strings
+     if(nex > 0) pch[26+ 1:nex] <- as.list(extras)
+     plot(rx, ry, type="n", axes = FALSE, xlab = "", ylab = "",
+          main = main)
+     abline(v = ix, h = iy, col = "lightgray", lty = "dotted")
+     for(i in 1:np) {
+       pc <- pch[[i]]
+       ## 'col' symbols with a 'bg'-colored interior (where available) :
+       points(ix[i], iy[i], pch = pc, col = col, bg = bg, cex = cex)
+       if(cextext > 0)
+           text(ix[i] - 0.3, iy[i], pc, col = coltext, cex = cextext)
+     }
+   }
> 
> 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
> 
> # specify the data 
> x <- c(1:10); y <- x; z <- 10/x
> 
> # create extra margin room on the right for an axis 
> par(mar=c(5, 4, 4, 8) + 0.1)
> 
> # plot x vs. y 
> plot(x, y,type="b", pch=21, col="red", 
+    yaxt="n", lty=3, xlab="", ylab="")
> 
> # add x vs. 1/x 
> lines(x, z, type="b", pch=22, col="blue", lty=2)
> 
> # draw an axis on the left 
> axis(2, at=x,labels=x, col.axis="red", las=2)
> 
> # draw an axis on the right, with smaller text and ticks 
> axis(4, at=z,labels=round(z,digits=2),
+   col.axis="blue", las=2, cex.axis=0.7, tck=-.01)
> 
> # add a title for the right axis 
> mtext("y=1/x", side=4, line=3, cex.lab=1,las=2, col="blue")
> 
> # add a main title and bottom and left axis labels 
> title("An Example of Creative Axes", xlab="X values",
+    ylab="Y=X")

座標軸

圖例使用legend()函數控制

參數 描述
x,y 圖例所在位置,可使用」bottom」,」bottomleft」,」left」,」topleft」,」top」,」topright」,」right」,」bottomleft」,」center」來指定。
inset 設置在主繪圖邊距
title 圖例的標題
legend 圖例的內容
其它par()可用的參數
> attach(mtcars)
> boxplot(mpg~cyl, main="Milage by Car Weight",
+   	 yaxt="n", xlab="Milage", horizontal=TRUE,
+    col=terrain.colors(3))
> legend("topright", inset=.05, title="Number of Cylinders",
+   	 c("4","6","8"), fill=terrain.colors(3), horiz=TRUE)

圖例

文本框使用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)
> plot(wt, mpg, main="Milage vs. Car Weight", 
+   	 xlab="Weight", ylab="Mileage", pch=18, col="blue")
> text(wt, mpg, row.names(mtcars), cex=0.6, pos=4, col="red")

文本框

六,各種圖型

點,線,面

點:points,線:abline,lines,segments,面:box,polygon,polypath,rect,特殊的:arrows,symbols

points不只僅能夠畫前文中pch所設定的任意一個符號,還能夠以字符爲符號。

> ## ------------ test code for various pch specifications -------------
> # Try this in various font families (including Hershey)
> # and locales.  Use sign=-1 asserts we want Latin-1.
> # Standard cases in a MBCS locale will not plot the top half.
> TestChars <- function(sign=1, font=1, ...)
+ {
+    if(font == 5) { sign <- 1; r <- c(32:126, 160:254)
+    } else if (l10n_info()$MBCS) r <- 32:126 else r <- 32:255
+    if (sign == -1) r <- c(32:126, 160:255)
+    par(pty="s")
+    plot(c(-1,16), c(-1,16), type="n", xlab="", ylab="",
+         xaxs="i", yaxs="i")
+    grid(17, 17, lty=1)
+    for(i in r) try(points(i%%16, i%/%16, pch=sign*i, font=font,...))
+ }
> TestChars()
> try(TestChars(sign=-1))

畫點

abline能夠由斜率和截距來肯定一條直線,lines能夠鏈接兩個或者多個點,segments能夠按起止位置畫線。

> require(stats)
> sale5 <- c(6, 4, 9, 7, 6, 12, 8, 10, 9, 13)
> plot(sale5,new=T)
> abline(lsfit(1:10,sale5))
> abline(lsfit(1:10,sale5, intercept = FALSE), col= 4)
> abline(h=6, v=8, col = "gray60")
> text(8,6, "abline( h = 6 )", col = "gray60", adj = c(0, -.1))
> abline(h = 4:8, v = 6:12, col = "lightgray", lty=3)
> abline(a=1, b=2, col = 2)
> text(5,11, "abline( 1, 2 )", col=2, adj=c(-.1,-.1))
> segments(6,4,9,5,col="green")
> text(6,5,"segments(6,4,9,5)")
> lines(sale5,col="pink")

線段

box畫出當前盒子的邊界,polygon畫多邊形,polypath畫路徑,rect畫距形。

> x <- c(1:9,8:1)
> y <- c(1,2*(5:3),2,-1,17,9,8,2:9)
> op <- par(mfcol=c(3,1))
> for(xpd in c(FALSE,TRUE,NA)) {
+   plot(1:10, main = paste("xpd =", xpd))
+   box("figure", col = "pink", lwd=3)
+   polygon(x,y, xpd=xpd, col="orange", lty=2, lwd=2, border="red")
+ }
> par(op)
> plotPath <- function(x, y, col = "grey", rule = "winding") {
+     plot.new()
+     plot.window(range(x, na.rm = TRUE), range(y, na.rm = TRUE))
+     polypath(x, y, col = col, rule = rule)
+     if (!is.na(col))
+         mtext(paste("Rule:", rule), side = 1, line = 0)
+ }
> 
> plotRules <- function(x, y, title) {
+     plotPath(x, y)
+     plotPath(x, y, rule = "evenodd")
+     mtext(title, side = 3, line = 0)
+     plotPath(x, y, col = NA)
+ }
> 
> op <- par(mfrow = c(5, 3), mar = c(2, 1, 1, 1))
> 
> plotRules(c(.1, .1, .9, .9, NA, .2, .2, .8, .8),
+           c(.1, .9, .9, .1, NA, .2, .8, .8, .2),
+           "Nested rectangles, both clockwise")
> plotRules(c(.1, .1, .9, .9, NA, .2, .8, .8, .2),
+           c(.1, .9, .9, .1, NA, .2, .2, .8, .8),
+           "Nested rectangles, outer clockwise, inner anti-clockwise")
> plotRules(c(.1, .1, .4, .4, NA, .6, .9, .9, .6),
+           c(.1, .4, .4, .1, NA, .6, .6, .9, .9),
+           "Disjoint rectangles")
> plotRules(c(.1, .1, .6, .6, NA, .4, .4, .9, .9),
+           c(.1, .6, .6, .1, NA, .4, .9, .9, .4),
+           "Overlapping rectangles, both clockwise")
> plotRules(c(.1, .1, .6, .6, NA, .4, .9, .9, .4),
+           c(.1, .6, .6, .1, NA, .4, .4, .9, .9),
+           "Overlapping rectangles, one clockwise, other anti-clockwise")
> 
> par(op)
> require(grDevices)
> ## set up the plot region:
> op <- par(bg = "thistle")
> plot(c(100, 250), c(300, 450), type = "n", xlab="", ylab="",
+      main = "2 x 11 rectangles; 'rect(100+i,300+i,  150+i,380+i)'")
> i <- 4*(0:10)
> ## draw rectangles with bottom left (100, 300)+i
> ## and top right (150, 380)+i
> rect(100+i, 300+i, 150+i, 380+i, col=rainbow(11, start=.7,end=.1))
> rect(240-i, 320+i, 250-i, 410+i, col=heat.colors(11), lwd=i/5)
> ## Background alternating  ( transparent / "bg" ) :
> j <- 10*(0:5)
> rect(125+j, 360+j,   141+j, 405+j/2, col = c(NA,0),
+      border = "gold", lwd = 2)
> rect(125+j, 296+j/2, 141+j, 331+j/5, col = c(NA,"midnightblue"))
> mtext("+  2 x 6 rect(*, col = c(NA,0)) and  col = c(NA,\"m..blue\"))")

多邊形

路徑

矩形

arrows用於畫箭頭,symbols用於畫符號

> ## Note that  example(trees)  shows more sensible plots!
> N <- nrow(trees)
> with(trees, {
+ ## Girth is diameter in inches
+ symbols(Height, Volume, circles = Girth/24, inches = FALSE,
+         main = "Trees' Girth") # xlab and ylab automatically
+ ## Colours too:
+ op <- palette(rainbow(N, end = 0.9))
+ symbols(Height, Volume, circles = Girth/16, inches = FALSE, bg = 1:N,
+         fg = "gray30", main = "symbols(*, circles = Girth/16, bg = 1:N)")
+ palette(op)
+ })

符號

畫圓

> library(plotrix)
> plot(1:5,seq(1,10,length=5),type="n",xlab="",ylab="",main="Test draw.circle")
>  draw.circle(2,4,c(1,0.66,0.33),border="purple",
+   col=c("#ff00ff","#ff77ff","#ffccff"),lty=1,lwd=1)
>  draw.circle(2.5,8,0.6,border="red",lty=3,lwd=3)
>  draw.circle(4,3,0.7,border="green",lty=1,lwd=1)
>  draw.circle(3.5,7,0.8,border="blue",lty=2,lwd=2)

散點圖及趨勢線

一維點圖使用dotchart函數。

> # Dotplot: Grouped Sorted and Colored
> # Sort by mpg, group and color by cylinder 
> x <- mtcars[order(mtcars$mpg),] # sort by mpg
> x$cyl <- factor(x$cyl) # it must be a factor
> x$color[x$cyl==4] <- "red"
> x$color[x$cyl==6] <- "blue"
> x$color[x$cyl==8] <- "darkgreen"	
> dotchart(x$mpg,labels=row.names(x),cex=.7,groups= x$cyl,
+   	 main="Gas Milage for Car Models\ngrouped by cylinder",
+    xlab="Miles Per Gallon", gcolor="black", color=x$color)

一維點圖

二維散點圖使用plot函數。直趨勢線使用abline函數,擬合曲線在擬合後使用line函數繪製。

> attach(mtcars)
> plot(wt, mpg, main="Scatterplot Example", 
+   	 xlab="Car Weight ", ylab="Miles Per Gallon ", pch=19)
> # Add fit lines
> abline(lm(mpg~wt), col="red") # regression line (y~x) 
> lines(lowess(wt,mpg), col="blue") # lowess line (x,y)

點陣圖

曲線

曲線使用lines函數。其type參數可使用」p」,」l」,」o」,」b,c」,」s,S」,」h」,」n」等。

> x <- c(1:5); y <- x # create some data
> par(pch=22, col="blue") # plotting symbol and color 
> par(mfrow=c(2,4)) # all plots on one page 
> opts = c("p","l","o","b","c","s","S","h") 
> for(i in 1:length(opts)){ 
+   heading = paste("type=",opts[i]) 
+   plot(x, y, main=heading) 
+   lines(x, y, type=opts[i]) 
+ }

曲線

柱狀圖

普通的柱狀圖使用barplot函數。其參數horiz=TRUE表示水平畫圖,beside=TRUE表示若是是多組數據的話,在並排畫圖,不然原位堆疊畫圖。

> par(mfrow=c(1,2))
> counts <- table(mtcars$vs, mtcars$gear)
> barplot(counts, main="Car Distribution by Gears and VS",
+   xlab="Number of Gears", col=c("darkblue","red"),
+  	 legend = rownames(counts),horiz=TRUE)
> barplot(counts, main="Car Distribution by Gears and VS",
+   xlab="Number of Gears", col=c("darkblue","red"),
+  	 legend = rownames(counts), beside=TRUE)

bar圖

柱狀統計圖使用hist函數。其breaks參數設置每組的範圍。使用density函數能夠擬合曲線。

> hist(mtcars$mpg, breaks=12)
> dens<-density(mtcars$mpg)
> lines(dens$x,dens$y*100,col="red")

柱狀圖

餅圖

餅圖使用pie函數。

> x<-table(mtcars$gear)
> pie(x,label=paste("gear=",rownames(x),sep=""))

餅圖

3維餅圖使用plotrix庫中的pie3D函數。

> x<-table(mtcars$gear)
> pie3D(x,labels=paste("gear=",rownames(x),sep=""),explode=0.1)

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", 
+   	 xlab="Number of Cylinders", ylab="Miles Per Gallon")
> boxplot(len~supp*dose, data=ToothGrowth, notch=TRUE, 
+   col=(c("gold","darkgreen")),
+   main="Tooth Growth", xlab="Suppliment and Dose")

箱線圖

若是我想在箱線圖上疊加樣品點,即所謂的蜂羣圖,如何作呢?

> source("http://bioconductor.org/biocLite.R")
> biocLite(c("beeswarm","ggplot2"))
> library(beeswarm)
> library(ggplot2)
> data(breast)
> beeswarm <- beeswarm(time_survival ~ event_survival,
+             data = breast, method = 'swarm',
+             pwcol = ER)[, c(1, 2, 4, 6)]
> colnames(beeswarm) <- c("x", "y", "ER", "event_survival")
> 
> beeswarm.plot <- ggplot(beeswarm, aes(x, y)) +
+   xlab("") +
+   scale_y_continuous(expression("Follow-up time (months)"))
> beeswarm.plot2 <- beeswarm.plot + geom_boxplot(aes(x, y,
+   group = round(x)), outlier.shape = NA)
> beeswarm.plot3 <- beeswarm.plot2 + geom_point(aes(colour = ER)) +
+   scale_colour_manual(values = c("black", "red")) +
+   scale_x_continuous(breaks = c(1:2),
+ labels = c("Censored", "Metastasis"), expand = c(0, 0.5))
> print(beeswarm.plot3)

蜂羣圖

> require(beeswarm)
> data(breast)
>  
> beeswarm(time_survival ~ event_survival, data = breast,
+         method = 'swarm',
+         pch = 16, pwcol = as.numeric(ER),
+         xlab = '', ylab = 'Follow-up time (months)',
+         labels = c('Censored', 'Metastasis'))
>  
> boxplot(time_survival ~ event_survival, 
+         data = breast, add = T, 
+         names = c("",""), col="#0000ff22")

蜂羣圖

分枝樹

> require(graphics)
> opar<-par(mfrow=c(2,1),mar=c(4,3,0.5,0.5))
> hc <- hclust(dist(USArrests), "ave")
> plot(hc,main="")
> plot(hc, hang = -1,main="")
> par(opar)

分枝樹

文氏圖

> library(limma)
> Y <- matrix(rnorm(100*6),100,6)
> Y[1:10,3:4] <- Y[1:10,3:4]+3
> Y[1:20,5:6] <- Y[1:20,5:6]+3
> design <- cbind(1,c(0,0,1,1,0,0),c(0,0,0,0,1,1))
> fit <- eBayes(lmFit(Y,design))
> results <- decideTests(fit)
> a <- vennCounts(results)
> print(a)
     x1 x2 x3 Counts
[1,]  0  0  0     89
[2,]  0  0  1     11
[3,]  0  1  0      0
[4,]  0  1  1      0
[5,]  1  0  0      0
[6,]  1  0  1      0
[7,]  1  1  0      0
[8,]  1  1  1      0
attr(,"class")
[1] "VennCounts"
> vennDiagram(a)
> vennDiagram(results,include=c("up","down"),counts.col=c("red","green"))

文氏圖

七,綜合應用

點陣圖加兩方向柱狀圖

> def.par <- par(no.readonly = TRUE) # save default, for resetting...
> 
> x <- pmin(3, pmax(-3, rnorm(50)))
> y <- pmin(3, pmax(-3, rnorm(50)))
> xhist <- hist(x, breaks=seq(-3,3,0.5), plot=FALSE)
> yhist <- hist(y, breaks=seq(-3,3,0.5), plot=FALSE)
> top <- max(c(xhist$counts, yhist$counts))
> xrange <- c(-3,3)
> yrange <- c(-3,3)
> nf <- layout(matrix(c(2,0,1,3),2,2,byrow=TRUE), c(3,1), c(1,3), TRUE)
> #layout.show(nf)
> 
> par(mar=c(3,3,1,1))
> plot(x, y, xlim=xrange, ylim=yrange, xlab="", ylab="")
> par(mar=c(0,3,1,1))
> barplot(xhist$counts, axes=FALSE, ylim=c(0, top), space=0)
> par(mar=c(3,0,1,1))
> barplot(yhist$counts, axes=FALSE, xlim=c(0, top), space=0, horiz=TRUE)
> 
> par(def.par)

點陣+柱狀

帶偏差的點線圖

> # Clustered Error Bar for Groups of Cases. 
> # Example: Experimental Condition (Stereotype Threat Yes/No) x Gender (Male / Female)
> # The following values would be calculated from data and are set fixed now for 
> # code reproduction
> 
> means.females <- c(0.08306698, -0.83376319)
> stderr.females <- c(0.13655378, 0.06973371)
> 
> names(means.females) <- c("No","Yes")
> names(stderr.females) <- c("No","Yes")
> 
> means.males <- c(0.4942997, 0.2845608)
> stderr.males <- c(0.07493673, 0.18479661)
> 
> names(means.males) <- c("No","Yes")
> names(stderr.males) <- c("No","Yes")
> 
> # Error Bar Plot
> 
> library (gplots)
> 
> # Draw the error bar for female experiment participants:
> plotCI(x = means.females, uiw = stderr.females, lty = 2, xaxt ="n", xlim = c(0.5,2.5), ylim = c(-1,1), gap = 0, ylab="Microworld Performance (Z Score)", xlab="Stereotype Threat", main = "Microworld performance over experimental conditions")
> 
> # Add the males to the existing plot
> plotCI(x = means.males, uiw = stderr.males, lty = 1, xaxt ="n", xlim = c(0.5,2.5), ylim = c(-1,1), gap = 0, add = TRUE)
> 
> # Draw the x-axis (omitted above)
> axis(side = 1, at = 1:2, labels = names(stderr.males), cex = 0.7)
> 
> # Add legend for male and female participants
> legend(2,1,legend=c("Male","Female"),lty=1:2)

偏差圖

偏差繪圖plotCI增強版是plotmeans,具體可以使用?plotmeans來試用它。這裏就很少講了。

帶偏差的柱狀圖。仍是使用gplots包

> library(gplots)
> # Example with confidence intervals and grid
> hh <- t(VADeaths)[, 5:1]
> mybarcol <- "gray20"
> ci.l <- hh * 0.85
> ci.u <- hh * 1.15
> mp <- barplot2(hh, beside = TRUE,
+         col = c("lightblue", "mistyrose",
+                 "lightcyan", "lavender"),
+         legend = colnames(VADeaths), ylim = c(0, 100),
+         main = "Death Rates in Virginia", font.main = 4,
+         sub = "Faked 95 percent error bars", col.sub = mybarcol,
+         cex.names = 1.5, plot.ci = TRUE, ci.l = ci.l, ci.u = ci.u,
+         plot.grid = TRUE)
> mtext(side = 1, at = colMeans(mp), line = 2,
+       text = paste("Mean", formatC(colMeans(hh))), col = "red")
> box()

帶偏差的柱狀圖

漂亮的箱線圖

> require(gplots) #for smartlegend
> 
> data(ToothGrowth)
> boxplot(len ~ dose, data = ToothGrowth,
+         boxwex = 0.25, at = 1:3 - 0.2,
+         subset= supp == "VC", col="yellow",
+         main="Guinea Pigs' Tooth Growth",
+         xlab="Vitamin C dose mg",
+         ylab="tooth length", ylim=c(0,35))
> boxplot(len ~ dose, data = ToothGrowth, add = TRUE,
+         boxwex = 0.25, at = 1:3 + 0.2,
+         subset= supp == "OJ", col="orange")
> 
> smartlegend(x="left",y="top", inset = 0,
+             c("Ascorbic acid", "Orange juice"),
+             fill = c("yellow", "orange"))

箱線圖

基因芯片熱圖,具體參考http://www2.warwick.ac.uk/fac/sci/moac/students/peter_cock/r/heatmap/

> library("ALL")
> data("ALL")
> eset <- ALL[, ALL$mol.biol %in% c("BCR/ABL", "ALL1/AF4")]
> library("limma")
> f <- factor(as.character(eset$mol.biol))
> design <- model.matrix(~f)
> fit <- eBayes(lmFit(eset,design))
> selected  <- p.adjust(fit$p.value[, 2]) <0.005
> esetSel <- eset [selected, ]
> color.map <- function(mol.biol) { if (mol.biol=="ALL1/AF4") "#FF0000" else "#0000FF" }
> patientcolors <- unlist(lapply(esetSel$mol.bio, color.map))
> library("gplots")
> heatmap.2(exprs(esetSel), col=redgreen(75), scale="row", ColSideColors=patientcolors,
+            key=TRUE, symkey=FALSE, density.info="none", trace="none", cexRow=0.5)

點柱圖(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)
> data(breast)
> head(breast)
            ER      ESR1     ERBB2 time_survival event_survival
100.CEL.gz neg  8.372133 13.085894            39              1
103.CEL.gz pos 10.559356  9.491683            97              0
104.CEL.gz pos 12.299905  9.599574            11              1
105.CEL.gz pos 10.776632  9.681747            99              0
106.CEL.gz pos 10.505124  9.436763            40              1
107.CEL.gz neg 10.377741  8.695576            94              0
> require(plotrix)
> cluster<-cluster.overplot(breast$event_survival, breast$time_survival)
> png("dothist.png",width=1000,height=1000)
> opar<-par(mfrow=c(3,3))
> plot (breast$event_survival, breast$time_survival, main="Multiple points on coordinate",col=as.numeric(breast$ER),xaxt="n",xlim=c(-1,2))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> 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))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> plot(jitter(breast$event_survival), jitter(breast$time_survival), main="Using Jitter on x and y-axis",col=as.numeric(breast$ER),xaxt="n",xlim=c(-0.5,1.5))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> sunflowerplot(breast$event_survival, breast$time_survival, main="Using Sunflowers",xaxt="n",xlim=c(-0.5,1.5))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> plot(cluster, main="Using cluster.overplot",col=as.numeric(breast$ER),xaxt="n",xlim=c(-0.5,1.5))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> count.overplot(jitter(breast$event_survival), jitter(breast$time_survival), main="Using cout.overplot",col=as.numeric(breast$ER),xaxt="n")
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> sizeplot(breast$event_survival, breast$time_survival, main="Using sizeplot",col=as.numeric(breast$ER),xaxt="n",xlim=c(-0.5,1.5))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> beeswarm(time_survival ~ event_survival, data = breast,
+          method = 'swarm',
+          pch = 16, pwcol = as.numeric(ER),
+          xlab = '', ylab = 'Follow-up time (months)',
+          labels = c('Censored', 'Metastasis'))
> dev.off()
quartz
     2
> par(opar)

如下是解釋

在不少狀況下,咱們畫散點圖的時候,有許多點擁有相同的橫座標,若是咱們簡單的使用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))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))
> plot(jitter(breast$event_survival), jitter(breast$time_survival), main="Using Jitter on x and y-axis",col=as.numeric(breast$ER),xaxt="n",xlim=c(-0.5,1.5))
> axis(1,at=c(0,1),labels=c("Censored","Metastasis"))

咱們比較圖中上邊靠右的兩個圖,咱們發現,若是隻抖散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")
> axis(1,at=c(1,5,10),labels=c(paste("factor=",c(1,5,10),sep="")))

不一樣強度的jitter

在graphics包中提供了一個sunflowerplot的函數。它的目的是用花瓣數目多少來顯示落在同一座標上的點的數目。可是從中左圖看來,點多的時候效果並不是老是那麼好。

在plotrix包中提供了一些有意思的函數來解決點擠在一塊兒的這個問題,它們分別是cluster.overplot, count.overplot, sizeplot。這三個函數的效果如圖中及下靠左的兩個。cluster.overplot的方法相似抖散,count overplot的方法是使用數字來顯示落在同一座標上的點的數目,sizeplot的方法是使用不一樣大小是點來顯示落在同一座標上的點的數目。從效果來看,點多的時候效果也並不是理想。

而上一次提到過的蜂羣圖彷佛是解決這一問題的最佳方案。

咱們得出結論,在點數不一樣的狀況下,使用plotrix包及sunflowerplot是不錯的。但點數較多的狀況下,仍是使用jitter和beeswarm較爲穩妥。

咱們也可使用ggplot2包中的geom來繪製點柱圖

> require(beeswarm)
> data(breast)
> library(ggplot2)
> p<-ggplot(breast, aes(event_survival,time_survival))
> print(p+geom_jitter(aes(color=ER))+scale_colour_manual(value = c("black", "red"))+scale_x_continuous(breaks = c(0:1),labels = c("Censored", "Metastasis")))

ggplot點柱圖

還有一種圖,名稱爲Engelmann-Hecker-Plot, 由plotrix的ehplot來實現。

> data(iris);library(plotrix)
> ehplot(iris$Sepal.Length, iris$Species,
+ intervals=20, cex=1.8, pch=20, main="pch=20")
> ehplot(iris$Sepal.Width, iris$Species,
+ intervals=20, box=TRUE, median=FALSE, main="box=TRUE")
> ehplot(iris$Petal.Length, iris$Species,
+ pch=17, col="red", log=TRUE, main="pch=17")
> ehplot(iris$Petal.Length, iris$Species,
+ offset=0.06, pch=as.numeric(iris$Species), main="pch=as.numeric(iris$Species)")
> rnd <- sample(150)
> plen <- iris$Petal.Length[rnd]
> pwid <- abs(rnorm(150, 1.2))
> spec <- iris$Species[rnd]
> ehplot(plen, spec, pch=19, cex=pwid,
+ col=rainbow(3, alpha=0.6)[as.numeric(spec)], main="cex and col changes")

ehplot

 

座標中斷(axis breaks)

R當中的座標中斷通常都使用plotrix庫中的axis.break(), gap.plot(), gap.barplot(), gap.boxplot()等幾個函數來實現,例:

gap plot

> library(plotrix)
> opar<-par(mfrow=c(3,2))
> plot(sample(5:7,20,replace=T),main="Axis break test",ylim=c(2,8))
> axis.break(axis=2,breakpos=2.5,style="gap")
> axis.break(axis=2,breakpos=3.5,style="slash")
> axis.break(axis=2,breakpos=4.5,style="zigzag")
> twogrp<-c(rnorm(5)+4,rnorm(5)+20,rnorm(5)+5,rnorm(5)+22)
> gap.plot(twogrp,gap=c(8,16,25,35),
+  xlab="X values",ylab="Y values",xlim=c(1,30),ylim=c(0,25),
+  main="Test two gap plot with the lot",xtics=seq(0,30,by=5),
+  ytics=c(4,6,18,20,22,38,40,42),
+  lty=c(rep(1,10),rep(2,10)),
+  pch=c(rep(2,10),rep(3,10)),
+  col=c(rep(2,10),rep(3,10)),
+  type="b")
> gap.plot(21:30,rnorm(10)+40,gap=c(8,16,25,35),add=TRUE,
+   lty=rep(3,10),col=rep(4,10),type="l")
> gap.barplot(twogrp,gap=c(8,16),xlab="Index",ytics=c(3,6,17,20),
+   ylab="Group values",main="Barplot with gap")
> gap.barplot(twogrp,gap=c(8,16),xlab="Index",ytics=c(3,6,17,20),
+   ylab="Group values",horiz=TRUE,main="Horizontal barplot with gap")
> twovec<-list(vec1=c(rnorm(30),-6),vec2=c(sample(1:10,40,TRUE),20))
>  gap.boxplot(twovec,gap=list(top=c(12,18),bottom=c(-5,-3)),
+  main="Show outliers separately")
> gap.boxplot(twovec,gap=list(top=c(12,18),bottom=c(-5,-3)),range=0,
+  main="Include outliers in whiskers")
> par(opar)

從圖像效果上來看,這樣的座標中斷只能說實現了座標中斷,但效果上是很是通常的。甚至遠不如excel, openoffice當中出圖效果好。爲此,咱們須要對plotrix庫中的gap.plot作出修改,以達到滿意的效果。

 

最簡單的修改辦法就是在使用了gap.plot, gap.barplot, gap.boxplot以後從新使用axis.break來修改中斷類型,使得看上去美一點。

> axis.break(2,from,breakcol="snow",style="gap")
> axis.break(2,from*(1+0.02),breakcol="black",style="slash")
> axis.break(4,from*(1+0.02),breakcol="black",style="slash")
> axis(2,at=from)

使用上面的辦法能夠繪製出雙反斜線中斷,並能夠視實際狀況加油斷點起止位置。

改進的gap.plot

> library(plotrix)
> x<-c(1:5,6.9,7)
> y<-2^x
> from<-33
> to<-110
> opar<-par(mfrow=c(2,2))
> plot(x,y,type="b",main="normal plot")
> gap.plot(x,y,gap=c(from,to),type="b",main="gap plot")
> axis.break(2,from,breakcol="snow",style="gap")
> axis.break(2,from*(1+0.02),breakcol="black",style="slash")
> axis.break(4,from*(1+0.02),breakcol="black",style="slash")
> axis(2,at=from)
> gap.barplot(y,gap=c(from,to),col=as.numeric(x),main="barplot with gap")
> axis.break(2,from,breakcol="snow",style="gap")
> axis.break(2,from*(1+0.02),breakcol="black",style="slash")
> axis.break(4,from*(1+0.02),breakcol="black",style="slash")
> axis(2,at=from)
> gap.barplot(y,gap=c(from,to),col=as.numeric(x),horiz=T,main="Horizontal barplot with gap")
> axis.break(1,from,breakcol="snow",style="gap")
> axis.break(1,from*(1+0.02),breakcol="black",style="slash")
> axis.break(3,from*(1+0.02),breakcol="black",style="slash")
> axis(1,at=from) 
> par(opar)

來源:http://blog.qiubio.com:8080/rbioconductor-2

  這個總結的也不錯,推薦下:  ggplot2繪製Excel全部圖

相關文章
相關標籤/搜索