1. 程式人生 > >R語言學習2:繪圖

R語言學習2:繪圖

本系列是一個新的系列,在此係列中,我將和大家共同學習R語言。由於我對R語言的瞭解也甚少,所以本系列更多以一個學習者的視角來完成。 參考教材:《R語言實戰》第二版(Robert I.Kabacoff),書中所提到的[John Cook的優秀博文](https://www.johndcook.com/blog/r_language_for_programmers/),關於程式碼規範的《[來自Google的R語言編碼風格指南](https://nanx.me/rstyle/)》。 [Toc] ## Part 1:圖形引數 ### Unit 1:點型和線型 `plot()`是R中為物件作圖的一個泛型函式,它的輸出由所繪製物件的型別不同而不同。如果`x`和`y`是兩個等長的數字向量,則以下程式碼將繪製點集$(x,y)$,並用線段將其連線。 ```R plot(x, y, type="b") ``` 這裡`type="b"`代表同時繪製點和線。還有以下的幾種`type`屬性的選擇: - `"p"`:只繪製點,不繪製線段。 - `"l"`:只繪製線段,不繪製點。 - `"b"`:繪製點和線,但實線不通過點。 - `"o"`:繪製點和線,且實線會通過點,與`"b"`的視覺效果不同。 - `"h"`:只繪製各點到$x$軸的豎線,不繪製點和線。 - `"s"`:繪製階梯型曲線。 - `"S"`:繪製階梯型區間,但是階梯方向不同。 - `"n"`:不繪製任何點、線。 在使用`plot()`作圖**之前**,可以使用`par()`函式修改圖形的引數,這個函式可以任意次呼叫。在使用`par()`修改圖形引數之前,往往會加入以下兩句: ```R opar <- par(no.readonly=TRUE) ... par(opar) ``` 當呼叫`par(opar)`後,將還原**預設引數環境**。 以下是用於指定符號和線條型別的引數: - `pch`:指定繪製點時使用的符號,範圍是$\{0,1,\cdots,25\}$。 - `cex`:指定符號的大小,表示繪圖符號相對於預設大小的縮放倍數,預設值是1。 - `lty`:指定線條型別,範圍是$\{1,2,\cdots,6\}$。 - `lwd`:指定線條寬度,表示之於預設值的相對粗細,預設值是1。 也可以直接在`plot`處加上這四個引數: ```R plot(x, y, type="b", pch=11, lty=2, cex=2, lwd=2) ``` ### Unit 2:顏色 以下是用於指定顏色的引數: - `col`:預設的繪圖顏色,可以傳入一個向量並迴圈使用。 - `col.axis`:座標軸刻度文字的顏色。 - `col.lab`:座標軸標籤文字的顏色。 - `col.main`:標題顏色。 - `col.sub`:副標題顏色。 - `fg`:圖形前景色,如座標軸線。 - `bg`:圖形背景色。 顏色的指定,可以用顏色下標、顏色名字、十六進位制顏色值、RGB值、HSV值來指定,函式`colors()`可以返回所有可用顏色的名稱(657種)。 可以用`rainbow(n)`建立一個$n$種連續的彩虹形顏色列表,可以用`gray(vector)`來獲得一個灰度色列表,常用的`vector=0:n/n`,是一個$[0,1]$之間的均勻列表。 `RColorBrewer`是一個用於建立顏色的常用包,其中`brewer.pal(n, name)`可以從調色盤`name`中建立一個顏色值的向量,以下程式段是一個`brewer.par()`函式的使用示例。 ```R library(RColorBrewer) n <- 9 mycolor <- brewer.pal(n, "Set1") # 使用的顏色集合是"Set1" barplot(rep(1,n), col = mycolor) ``` 可以使用`display.brewer.all()`顯示所有調色盤的顏色,或者`display.brewer.pal(name)`顯示某個調色盤的顏色。`brewer.pal.info`命令可以給出所有調色盤的列表。 ### Unit 3:文字 字型族和字樣通過以下引數進行控制。 - `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`:字型磅值,文字的最終大小為`ps*cex`。 - `family`:繪製文字時使用的字型族,標準取值為`serif`(襯線)、`sans`(無襯線)、`mono`(等寬)。 字型族的設定稍顯複雜,**在Windows系統中**,`mono`對映為TT Courier New,`sarif`對映為TT Times New Roman,`sans`對映為TT Arial,這裡TT指True Type。如果想要使用其他字型,需要建立新的對映,使用`windowsFonts()`和`windowsFont()`來建立。 ```R x <- c(20, 30, 40, 45, 60) y <- c(16, 20, 27, 40, 60) windowsFonts( A=windowsFont("Arial Black"), B=windowsFont("Bookman Old Style"), C=windowsFont("Comic Sans MS") ) par(pch=17, lty=6, cex=2, lwd=3) # 注意cex引數也會對文字產生影響 par(col='red') par(font.main=4, family="C", ps=6) plot(x, y, type="b", main="A Simple Try") ```
### Unit 4:圖形尺寸與邊界尺寸 控制圖形尺寸和邊界大小的引數為: - `pin`:以英寸表示的圖形尺寸,是一個二元列表(寬和高)。 - `mai`:以數值向量表示的邊界大小,單位為英寸(下、左、上、右)。 - `mar`:以數值向量表示的邊界大小,單位為英分(下、左、上、右)。 ## Part 2:新增要素 ### Unit 1:新增標題和座標軸標籤 新增標題和座標軸標籤:使用`title()`函式,其呼叫格式為 ```R title(main="main title", sub="subtitle", xlab="x-axis label", ylab="y-axis label") ``` 可以在`title()`函式中新增其他圖形引數,如`col.main`、`col.lab`、`cex.lab`等。 ### Unit 2:添加個性化座標軸 如果要添加個性化的座標軸,通常要在`plot()`函式中設定一些圖形引數: - `ann`:取`FALSE`時,將不會畫出標題,包括主標題和副標題。 - `bty`:設定邊框樣式,預設為`"o"`表示全部畫出,還有`"l"`(左下)、`"7"`(右上)、`"c"`(上下左)、`"u"`(左下右)、`"]"`(上下右)、`"n"`(無)。 - `xaxs`和`yaxs`:設定$x, y$軸的範圍,預設為`"r"`表示比範圍略大,`"i"`表示和給定作圖範圍完全相同。 - `xaxt`和`yaxt`:可以取`"n"`,此時座標軸、刻度線和刻度值將不會畫出。 - `axes`:如果取`FALSE`,則所有座標軸和框線都不會被畫出。 新增自定義的座標軸:使用`axis()`函式,其呼叫格式為 ```R axis(side, at=, labels=, pos=, lty=, col=, las=, tck=, ...) ``` 各個引數的釋義為 - `side`:$\{1,2,3,4\}$,表示在圖形的哪一邊繪製座標軸(下、左、上、右)。 - `at`:數值型向量,表示需要繪製刻度線的位置。 - `labels`:字元型向量,刻度線旁的文字標籤,如果預設則直接使用`at`中的值。 - `pos`:座標軸線繪製位置的座標。 - `lty`:線條型別。 - `col`:線條和刻度線顏色。 - `las`:標籤平行於座標軸`=0`,垂直於座標軸`=2`。 - `tck`:刻度線的長度,以相對於繪圖區域大小的分數表示,預設為-0.01,負值表示在圖形外側。 ```R x <- c(20, 30, 40, 45, 60) y <- c(16, 20, 27, 40, 60) windowsFonts( A=windowsFont("Arial Black"), B=windowsFont("Bookman Old Style"), C=windowsFont("Comic Sans MS") ) par(pch=17, lty=6, cex=1, lwd=3) par(col='red') par(font.main=2, family="C", ps=12) plot(x, y, type="b", main="A Simple Try", yaxt="n") z <- c(20, 21, 22, 23, 24, 26, 28, 30, 35, 42, 50, 60) axis(4, at=z, labels=z, col.axis='blue', pos=50, las=2, lty=2, tck=-0.02, ) ```
### Unit 3:新增圖例和參考線 要新增參考線,應當使用`abline()`函式,其使用格式為 ```R abline(h=yvalues, v=xvalues) ``` 這裡`h`代表新增水平參考線的高度位置,`v`代表新增垂直參考線的水平位置。可以在其中新增其他圖形引數。 要新增圖例,應當使用`legend()`函式,其使用格式為 ```R legend(location, title, legend, ...) ``` - `location`:指定圖例的位置,可以給定圖例左上角的$x,y$座標,也可以使用`locator(1)`用滑鼠點選,還可以使用`bottom, bottomleft, left, topleft, top, topright, right, bottomright, center`等關鍵字。 - `title`:圖例標題的字串。 - `legend`:圖例標籤組成的字元型向量。 以下給出書上的案例: ```R rm(list=ls()) 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 = T) par(lwd=2, cex=1.5, font.lab=2) plot(dose, drugA, type="b", pch=15, lty=1, col="red", ylim=c(0,60), main="Drug A vs. Drug B", xlab="Drug Dosage", ylab="Drug Response") lines(dose, drugB, type="b", pch=17, lty=2, col="blue") abline(h=30, lwd=1.5, lty=2, col="gray") library(Hmisc) minor.tick(nx=3, ny=3, tick.ratio=0.5) # 新增次要刻度線 legend("topleft", inset=0.05, title="Drug Type", c("A", "B"), lty=c(1, 2), pch=c(15, 17), col=c("red", "blue")) par(opar) ```
### Unit 4:新增輔助文字 文字新增可以通過函式函式`text()`,向圖形內部(通常是各個點)新增文字,使用格式為 ```R text(location, "text to place", pos, ...) ``` - `location`:文字的位置引數,可以是一對$(x, y)$座標,也可以通過`location=locator(1)`用滑鼠來確定擺放位置。 - `pos`:文字相對於位置引數的方位,$\{1,2,3,4\}$代表下、左、上、右。還可以追加指定引數`offset`作為偏移量。 還可以通過`mtext()`向圖形的四個邊界之一新增文字,使用格式為 ```R mtext("text to place", side, line=n, ...) ``` - `side`:指定擺放文字的邊,$\{1,2,3,4\}$代表下、左、上、右。 - `line`:內移或外移文字,值越大,文字外移的程度越大。 - `adj`:文字可以向左下對齊`=0`,或向右上對齊`=1`。 ## Part 3:圖形組合 規則排布:可以使用`par()`函式中的圖形引數`mfrow=c(nrows, ncols)`來建立按行填充的、行數為`nrows`、列數為`ncols`的圖形矩陣。以下案例書上的例項程式碼,資料集為R語言內建的`mtcars`。 ```R rm(list=ls()) opar <- par(no.readonly = T) par(mfrow=c(2, 2)) # 將繪圖區域分成四塊 attach(mtcars) plot(wt, mpg, main="Scatterplot of wt vs. mpg") # 第一個圖 plot(wt, disp, main="Scatterplot of wt vs. disp") # 第二個圖 hist(wt, main="Histogram of wt") # 第三個圖 boxplot(wt, main="Boxplot of wt") # 第四個圖 detach(mtcars) par(opar) ``` 複雜排布:可以使用`layout(matrix)`函式來組合圖形,這裡`matrix`給定了圖形的所在位置,如 $$ \begin{pmatrix} 1 & 1 \\ 2 & 3 \end{pmatrix} $$ 就代表第一幅圖位於第一行的1、2列,第二幅圖位於第二行第一列,第三幅圖位於第二行第二列。 ```R rm(list=ls()) opar <- par(no.readonly = T) attach(mtcars) mat <- matrix(c(1, 1, 2, 3), nrow=2, ncol=2, byrow=T) layout(mat) # 按照mat矩陣給出劃分 hist(wt, main = "Graph_1") hist(mpg, main = "Graph_2") hist(disp, main = "Graph_3") detach(mtcars) par(opar) ``` 為了精細控制每幅圖形的相對大小,可以在`layout()`函式中使用`widths`和`heights`兩個引數,它們分別是各列寬度值構成的向量與各行寬度值構成的向量。現在,在上述程式碼中加入這兩個引數。 ```R rm(list=ls()) opar <- par(no.readonly = T) attach(mtcars) mat <- matrix(c(1, 1, 2, 3), nrow=2, ncol=2, byrow=T) layout(mat, widths = c(3, 1), heights = c(1, 1.5)) # 按照mat矩陣給出劃分 hist(wt, main = "Graph_1") hist(mpg, main = "Graph_2") hist(disp, main = "Graph_3") detach(mtcars) par(opar) ``` 精細控制:可以使用`par()`函式的引數`fig`來精細控制,它接受四個$[0,1]$之間的數,分別代表圖形在視窗內所佔有矩形的四個端點。一般還要加入`new=TRUE`,使得新加入的圖形與原圖形位於同樣的畫布中。 注意,如果遇到`Error in plot.new(): figure margins too large`,則應當**修改引數**,這是因為由於裝置的原因,子圖所需的大小與設定的引數衝