這裡介紹 ggplot
函數的基本圖層式繪圖使用方式。
ggplot
系統在繪圖時是以一種圖層式的概念在建立圖形的,每一張圖層上的資料可以有不同的來源、美學對應,而簡單版的 qplot
只允許單一資料來源以及一組美學對應,若要完全發揮 ggplot
系統的功能,就必須使用它的 ggplot
函數配合各式的圖層函數,這樣才能畫出更有彈性的圖形。
在使用 qplot
繪圖時,它其實自動幫使用者做了很多工作,從建立基本圖形物件、增加圖層到顯示繪圖結果等流程,以及選用各種的預設繪圖選項等,雖然這樣使用者非常方便就可以快速產生一張可用的圖形,不過同時也讓繪圖的彈性降低、可用的選項減少,無法繪製出比較複雜的圖形。
在 ggplot
系統上若要以標準的繪圖流程來畫圖,首先要使用 ggplot
這個函數來建立基本繪圖物件,其第一個 data
參數是指定資料來源的 data frame,而第二個 mapping
參數則是指定美學對應(aesthetic mapping),這兩個參數是設定繪圖的物件的預設值,若在這裡沒有設定的話,也可以在後續加入的圖層中再設定。
mapping
參數所指定的美學對應跟 qplot
中所使用的相同,只不過在這裡必須將對應的參數用 aes
函數包裝起來。下面這個範例是將 carat
變數對應到 x 軸、price
變數對應到 y 軸,而以顏色區隔 cut
變數。
my.plot <- ggplot(diamonds, aes(carat, price, colour = cut))
這裡建立的 my.plot
只是一個基本的繪圖物件,尚未包含任何圖層,所以還無法顯示任何圖形。
一個只包含 geom
參數的圖層是一個最簡單的圖層,其指定了繪製資料時所使用的幾何圖形。若在前面建立的繪圖物件上再加入一個 geom
指定為 point
的圖層,即可產生一張散佈圖:
my.plot <- my.plot + layer( geom = "point", stat = "identity", position = "identity", params = list(na.rm = FALSE) )
這裡我們以加號(+
)將圖層疊加至既有的繪圖物件上,被加入的新圖層會直接使用該繪圖物件上的資料來源以及美學對應參數。除了指定 geom
參數之外,另外還有兩個 stat
與 position
參數也要自行指定,這兩個參數可用來指定統計轉換與細部的幾何圖形位置調整,若不需要特別的轉換與調整的話,就指定為 "identity"
。params
則是用來指定 geom
與 stat
所需要的參數。
若要顯示圖形則將此繪圖物件輸出即可:
my.plot
若要繪製直方圖的話,要指定的參數就會稍微複雜一些:
my.plot2 <- ggplot(diamonds, aes(x = carat)) my.plot2 <- my.plot2 + layer( geom = "bar", stat = "bin", position = "identity", params = list( fill = "steelblue", binwidth = 0.2, na.rm = FALSE ) ) my.plot2
在產生直方圖時,我們需要使用 bin
這個統計轉換來計算直方圖每個 bin 的數值,然後再使用 bar
這個 geom
呈現圖形,標準的圖層建立程序可以讓使用者有很大的彈性,但相對上需要的操作也相當繁瑣。
為了簡化繪圖的工作,ggplot
系統上提供了非常多建立圖層用的簡化圖層函數,在使用者取用 geom
的同時也自動加上預設的 stat
與 position
,同樣的在取用 stat
時也會伴隨預設的 geom
,使用者只需要很直覺地指定少量的參數即可。
ggplot
中的簡化圖層函數都是以 geom_*
與 stat_*
的方式命名的,通常從函數的名稱就可以看出其作用為何。改用簡化圖層函數之後,建立 ggplot
圖層的動作就會變得很簡單,以上面繪製直方圖的範例來說,若以 geom_histogram
這個繪製直方圖的簡化圖層函數改寫後,就會變成這樣:
my.plot3 <- ggplot(diamonds, aes(x = carat)) my.plot3 <- my.plot3 + geom_histogram(binwidth = 0.2, fill = "steelblue") my.plot3
產生的圖形相同,但是操作卻簡單很多。
大部分的 ggplot
的簡化圖層函數都有一些共通的參數:
mapping
:指定美學對應,指定時需要以 aes
函數包裝,若沒有指定則會使用繪圖物件的預設值。data
:指定資料來源的 data frame,通常都會省略,並直接使用繪圖物件的預設值。...
:geom
與 stat
所使用的參數,例如直方圖的 bin 寬度等。geom
與 stat
:自行指定要使用的 geom
與 stat
,改變預設的設定。position
:指定細部的資料位置調整。以上這些參數都可以省略,不指定的話就會使用內部的預設值。
在 ggplot
函數與圖層函數的參數順序有些小差異,在 ggplot
中第一個參數是 data
、第二個是 mapping
,但是在圖層函數中剛好相反,這樣的設計是因為一般在使用 ggplot
繪圖時,通常都會在 ggplot
中指定資料,而加入圖層時只會指定美學對應的參數。
ggplot
的圖層可以直接加在 ggplot
或 qplot
所產生的繪圖物件上,事實上 qplot
只是將建立繪圖物件與加入圖層的動作包裝成一個函數而已,其效果跟 ggplot
函數是相同的。
以下是幾種 ggplot
與 qplot
的寫法比較。
# 做法一 ggplot(msleep, aes(sleep_rem / sleep_total, awake)) + geom_point() # 做法二 qplot(sleep_rem / sleep_total, awake, data = msleep)
加入平滑曲線的範例:
# 做法一 qplot(sleep_rem / sleep_total, awake, data = msleep) + geom_smooth() # 做法二 qplot(sleep_rem / sleep_total, awake, data = msleep, geom = c("point", "smooth")) # 做法三 ggplot(msleep, aes(sleep_rem / sleep_total, awake)) + geom_point() + geom_smooth()
儲存在變數當中的 ggplot
繪圖物件可以使用 summary
查看其內容,透過這種方式可以在不需要把圖形畫出來的情況下檢查圖形的細節:
my.plot4 <- ggplot(msleep, aes(sleep_rem / sleep_total, awake)) summary(my.plot4)
data: name, genus, vore, order, conservation, sleep_total, sleep_rem, sleep_cycle, awake, brainwt, bodywt [83x11] mapping: x = sleep_rem/sleep_total, y = awake faceting: facet_null()
my.plot4 <- my.plot4 + geom_point() summary(my.plot4)
data: name, genus, vore, order, conservation, sleep_total, sleep_rem, sleep_cycle, awake, brainwt, bodywt [83x11] mapping: x = sleep_rem/sleep_total, y = awake faceting: facet_null() ----------------------------------- geom_point: na.rm = FALSE stat_identity: na.rm = FALSE position_identity
ggplot
的圖層本身就是一種 R 的物件,也可以儲存在變數當中,減少重複的程式碼,例如我們可以用不同的資料來源來建立多個繪圖物件,然後套用相同的圖層,若後來要更換圖層時,也僅需要更改一個地方。以下的範例中我們建立了一個圖層,套用在不同的繪圖物件上。
bestfit <- geom_smooth(method = "lm", se = F, color = alpha("steelblue", 0.5), size = 2) qplot(sleep_rem, sleep_total, data = msleep) + bestfit qplot(awake, brainwt, data = msleep, log = "y") + bestfit qplot(bodywt, brainwt, data = msleep, log = "xy") + bestfit