分類: R

R ggplot2 教學:圖層式繪圖

資料來源

ggplot 的資料來源一定要是 data frame,它不像 R 的其他繪圖系統一樣同時可以接受一般的向量,而這樣嚴格的設計也是有它的優點,除了讓程式碼的語法統一之外,也可以方便置換資料,直接以既有的圖層組合產生新的圖形。

若要改變一個 ggplot 繪圖物件的資料來源,可以使用 %+% 運算子:

my.plot5 <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) + geom_point()
my.plot5

散佈圖

使用 %+% 運算子抽換資料來源的 data frame:

mtcars.trans <- transform(mtcars, mpg = mpg ^ 2)
my.plot5 %+% mtcars.trans

散佈圖

ggplot 在指定資料來源之後,會將資料複製一份並儲存在繪圖物件當中,後續若資料更動時,ggplot 的繪圖並不會受影響,另外由於這樣的特性,我們可以將 ggplot 繪圖物件儲存至硬碟中,之後重新載入與繪圖時也不需要載入其餘任何資料。

美學對應

美學對應中敘述了資料中的各個變數如何與圖形上的各種屬性對應,指定美學對應的各種參數時要使用 aes 函數包裝起來,例如:

aes(x = weight, y = height, color = age)

這個設定會將 x 軸指定為 weight 變數、y 軸指定為 height 變數,而顏色(color)則是指定為 age 變數。這些變數都會從資料來源的 data frame 中取得,不需要以錢字號的方式指定,這種設計可以讓使用者將所需要使用的變數都包裝在一個 data frame 中,方便統一管理。

在指定對應關係時,也可以運用各種數學函數:

aes(weight, height, colour = sqrt(age))

aes 中只能使用繪圖物件或圖層資料來源 data frame 中的變數,不可以指定為其他全域的變數,這個限制是要確保每一個 ggplot 物件本身都可以獨立運作,在經過儲存與重新載入之後也不會有問題。

繪圖與圖層

預設的美學對應可以在繪圖物件建立時就指定,這是比較常見的使用方式:

my.plot6 <- ggplot(mtcars, aes(x = mpg, y = wt))
my.plot6 <- my.plot6 + geom_point()
summary(my.plot6)
data: mpg, cyl, disp, hp, drat, wt, qsec, vs, am, gear, carb [32x11]
mapping:  x = mpg, y = wt
faceting: facet_null() 
-----------------------------------
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity

除此之外,也可以在繪圖物件建立之後,再加上 aes 來指定:

my.plot7 <- ggplot(mtcars)
my.plot7 <- my.plot7 + aes(x = mpg, y = wt)
my.plot7 <- my.plot7 + geom_point()
summary(my.plot7)
data: mpg, cyl, disp, hp, drat, wt, qsec, vs, am, gear, carb [32x11]
mapping:  x = mpg, y = wt
faceting: facet_null() 
-----------------------------------
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity

在繪圖物件中的美學對應設定可以在圖層中增加、修改或刪除,例如:

my.plot7 + geom_point(aes(colour = factor(cyl)))
my.plot7 + geom_point(aes(y = disp))

如果要刪除某一個美學對應參數,就把該參數設定為 NULL 即可,例如:

aes(y = NULL)

在圖層中更改美學對應的設定,其效果只會影響該圖層本身,對全域的設定沒有影響。

設定與對應

除了將美學對應以 aes 函數指定為資料的變數之外,也可以使用一般參數的方式指定為一個固定的值,例如將資料點的顏色指定為藍色:

my.plot8 <- ggplot(mtcars, aes(mpg, wt))
my.plot8 + geom_point(colour = "blue")

散佈圖

這裡在指定資料點的顏色時,並沒有加上 aes 函數,這種指定方式就是單純將資料點的顏色「設定」為藍色,這個做法跟加上 aes 函數的狀況完全不同。

my.plot8 + geom_point(aes(colour = "blue"))

散佈圖

加上 aes 函數之後是代表一種「對應」關係,這樣會在內部產生一個值為 "blue" 的變數,然後將顏色屬性對應到該變數,由於這個變數是只有一個值的類別型變數,所以在上色時會從預設的色盤上取出第一種顏色來為資料點上色,而預設的第一種顏色就是這裡看到的粉紅色。

如果在 qplot 函數中要設定這種固定的參數時,要額外使用 I 函數將參數值包起來,也就是 color = I("blue")

群組(Grouping)

ggplot 系統中的幾何圖形(geom)大致可分為個體型與集合型兩大類,個體型的幾何圖形在表現資料時,data frame 中的每一筆資料(亦即每一列)都會以一個幾何圖形呈現,例如 point 會以一個資料點表示一筆資料,而集合型的幾何圖形則會以一個幾何圖形表現多筆資料,通常這些資料都會先經過一些統計轉換,例如直方圖等。至於 linepath 則是介於兩者之間的幾何圖形,整條線雖然代表一組資料,但其中每一條線段都代表兩筆資料。

ggplot 系統上資料與幾何圖形之間的對應是由群組(group)這個美學對應所負責的,在預設的設定之下,ggplot 會以圖形上所有的類別型資料為基準來區分資料,大部分的狀況下這樣的設定都可以畫出使用者想要的結果,但若這樣的設定不符合使用者的需求,或是圖形上沒有類別型的資料時,就會需要自行指定群組的設定,也就是要自行指定一個可以用來區分組別的變數。

interaction 函數可以協助使用者將多個變數組合成一個,方便建立分組用的變數。

基本群組

這裡我們以 nlme 套件中的 Oxboys 資料集來做示範,在這個資料集中包含了許多個體的時間序列資料,如果只是單純將時間序列畫出來,圖形會有問題:

my.plot9 <- ggplot(Oxboys, aes(age, height)) +
  geom_line()

時間序列圖

上面的圖形是將所有個體的資料都混合在一起繪製,但我們通常會希望依據個體區分,畫出多條時間序列的線條,這時候就可以加上 group 參數,並將其指定為個體的變數:

my.plot9 <- ggplot(Oxboys, aes(age, height, group = Subject)) +
  geom_line()

時間序列圖

圖層與群組

有時候我們會希望在圖形上加上一些標示總體趨勢的幾何圖形,讓整個圖形除了有每個個體的細部資訊之外,也可以同時呈現整體的資料分佈走向。在上面這個例子中若要加上一條線性迴歸線,可以使用 geom_smooth 配合 method = "lm" 參數,不過若只是這樣加上去,結果可能不如預期:

my.plot9 + geom_smooth(method="lm", se = F)

時間序列圖

由於我們在繪圖物件中已經設定了 group 參數,所以再加上迴歸線的圖層時,也會套用該 group 的設定,也就是說它會對每一個個體畫出各自的迴歸線,但我們想要的是使用全部的資料畫出一條迴歸線,這時候就可以將 group 設定為一個固定的值,也就是取消群組的功能:

my.plot9 + geom_smooth(aes(group = 1), method="lm", size = 2, se = F)

時間序列圖

在加入圖層時透過指定新的群組設定,就可以做出很多的變化。

下面這個圖是將 height 依據 Occasion 畫出的箱形圖:

boysbox <- ggplot(Oxboys, aes(Occasion, height)) + geom_boxplot()

由於在繪製箱形圖時是使用 Occasion 這個離散型的變數,所以預設的狀況下就會以這個變數分組,所以不需要特別指定 group 參數。接著如果要將每個個體的資料標示出來,就會需要自行指定分組的方式:

boysbox + geom_line(aes(group = Subject), color = "blue")

在這裡我們使用 geom_line 配合 group 參數,讓它依據 Subject 區分資料,畫出每個個體的資料,並且另外加上 color 參數設定線條顏色。

美學對應與幾何圖形

個體型的幾何圖形在美學對應上很單純,個別資料的美學對應性質都是以一對一的方式對應到幾何圖形上,但是對於集合型的幾何圖形而言,就會是一個問題。

如果是在繪製 line 或是 path 的線段時,第一條線段會使用第一個點的顏色,而第二條線段會使用第二個點的顏色,以次類推,也就是說最後一個點的顏色並不會被使用到。

my.df <- data.frame(x = 1:3, y = 1:3, z = 1:3)
qplot(x, y, data = my.df, color = factor(z), size = I(5)) +
  geom_line(size = 3, group = 1)

至於其他類型的集合型幾何圖形,只有在每一筆資料的屬性都相同時才會被使用,否則就會直接使用預設值,這個問題通常只會發生在連續型的變數上,因為如果是類別型的變數在使用時,ggplot 會自動將資料依據變數分組,所以每一組內部的變數值都會是一樣的,這個狀況在繪製直方圖時很常見。

qplot(color, data = diamonds, geom = "bar",
  fill = cut)

Page: 1 2 3 4

G. T. Wang

個人使用 Linux 經驗長達十餘年,樂於分享各種自由軟體技術與實作文章。

Share
Published by
G. T. Wang

Recent Posts

[DIY] 自製凡士林火種

這裡介紹如何利用簡單的凡士林與...

3 年 ago

[DIY] 自製火影木葉、砂忍者村標誌雕刻木牌

本篇記錄我用路邊撿來的樟木與龍...

3 年 ago

收集龍眼木修剪枝幹用於木頭工藝

最近打算帶著阿玄做一些木工作品...

3 年 ago

[DIY] 樟木手工自製迷你手裏劍(忍者武器)

本篇記錄阿玄第一次使用木工工具...

3 年 ago

[DIY] 龍眼木手工自製木槌

本篇記錄我用自己砍的龍眼木還有...

3 年 ago

[DIY] 樟木手工自製苦無(忍者武器)

本篇記錄我自己用樟木的枝幹,以...

3 年 ago