使用ggplot2進行數據可視化:散點圖篇
The simple graph has brought more information to the data analyst’s mind than any other device. —John Tukey
在數據分析中,進行數據可視化是一個重要的步驟。在前期對數據進行初步探索時,數據可視化會讓我們對數據有一個初步的瞭解;而在後期進行分析和交流時,數據可視化可以爲別人提供更加有效、易讀的信息。
在R語言中,有這兩個繪圖系統:傳統繪圖系統和Grid繪圖系統,此外還有兩個基於Grid繪圖系統的主流拓展包:lattice和ggplot2。在這裏主要介紹的是ggplot2包在數據可視化中的運用。ggplot2提供了全面的、基於語法的、連貫一致的圖形生成系統,允許用戶創建新穎的、有創造性的數據可視化圖形。雖然ggplot2的學習曲線陡峭,但是隻要掌握其語法規則,能夠在很短的時間內生成達到出版水平的圖形。所以,ggplot2是R數據可視化中重要的擴展包。
使用散點圖觀察兩個連續性變量的關係
有時候,我們想要知道兩個連續性變量是否存在某種關係,如線性、非線性、正相關、負相關等等,我們通常繪製散點圖初步觀察這種關係是否存在。
使用的示例數據集
在這裏,我們主要是用的數據集是“mpg”。該數據集包含了1999-2008年部分車型以及其燃料消耗等數據。該數據集是ggplot2包一個示例數據集,我們可以使用查看該數據集前幾行:
library(ggplot2)
data(mpg)
head(mpg)
# A tibble: 6 x 11
manufacturer model displ year cyl trans drv cty hwy fl class
<chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
1 audi a4 1.8 1999 4 auto(l5) f 18 29 p compact
2 audi a4 1.8 1999 4 manual(m5) f 21 29 p compact
3 audi a4 2.0 2008 4 manual(m6) f 20 31 p compact
4 audi a4 2.0 2008 4 auto(av) f 21 30 p compact
5 audi a4 2.8 1999 6 auto(l5) f 16 26 p compact
6 audi a4 2.8 1999 6 manual(m5) f 18 26 p compact
此外,可以使用?mpg
在Rstudio上查看詳細的解釋。
散點圖的可視化
在這裏,我們想要知道的是,發動機排量(displ)和燃油效率(hwy)之間存在什麼關係。
- displ:發動機的排放量,單位升;
- hwy:highway miles per gallon,每加侖汽油行駛的距離,單位米/加侖。
根據平時的經驗來看,發動機排量越小,每加侖汽油行駛的距離就越長,即,燃油效率就越高。 那麼在這個數據集中,是怎樣的一種情況呢?在散點圖中,我們可以觀察到他們之間的關係。使用ggpolot2進行散點圖的繪製代碼如下:
library(ggplot2)
ggplot(mpg,mapping = aes(x=displ,y=hwy))+
geom_point()
我們可以從上圖看到,隨着發動機排量的升高,每加侖汽油行駛的距離就越短,發動機排量和燃油效率存在着線性的關係。對於上述的代碼,ggplot2到底是如何工作的?
在ggplot2中,我們是首先需要告訴函數使用哪一個數據集,然後給他規定橫軸和縱軸分別表示哪些變量。在上面的代碼中,我們在ggplot()
函數中規定了數據集以及橫縱座標所代表的變量。然而單單使用ggplot()
函數僅僅只能生成一個橫縱座標軸(下圖)。所以我們還需要告訴系統,我們想要畫的是什麼類型的圖,這個由geom_point()
函數來告訴系統,我們想畫的是散點圖。geom_point()
這種函數稱爲幾何函數,在ggplot2中,這樣的幾何函數有很多,如條形圖 :geom_bar()
,箱線圖:goem_boxplot()
,直方圖:geom_histogram()
等等。
我們在使用ggolot(mpg,mapping = aes(x=displ,y=hwy))
時,我們已經將橫軸和縱軸的變量設爲了全局變量。全局變量意味着後續的圖形全部是在這個橫縱座標下繪製的,比如,我們想添加一條光滑在這個圖形的基礎上添加一條光滑的曲線:
ggplot(mpg,mapping = aes(x=displ,y=hwy))+
geom_point()+
geom_smooth()
除了這種方法外,我們還可以在幾何函數下爲每一個圖形設置其橫軸及縱軸,當這樣設置時,意味着設置的橫軸與縱軸的變量僅僅適用於這個幾何函數。下面的代碼表示使用displ和hwy變量繪製散點圖,使用displ和cty變量繪製光滑曲線:
ggplot(mpg)+
geom_point(mapping = aes(x=displ,y=hwy))+
geom_smooth(mapping = aes(x=displ,y=cty))
雖然縱軸顯示的是hwy,但是光滑曲線並不是hwy爲縱軸進行繪製的。
分組
重新審視圖一的散點圖,我們發現有一些異常值,出乎我們的意料:這些車在大排量下居然也有着較好的燃油效率。這些異常值的是否與其他的因素有關,和什麼因素有關?這些在總體的數據中我們無法觀察到不同。所以我們需要對這些數據進行分組。在這個數據集中,我們注意到車輛有着不同的類型,因此,我們選擇對其車型進行分組,看看不同組別的汽車有什麼不同。
在ggplot2中,可以很簡便的看到各個分組的情況:
ggplot(mpg,mapping = aes(x=displ,y=hwy,colour = class))+
geom_point()
需要注意的是,ggplot2中,分組的函數必須放在aes()
中,否則這會出現錯誤。
分組之後,我們發現異常值基本都屬於一種車型:2seater。這種車型是一種跑車,擁有者大排量的發動機和較輕的車身,所以使其在同樣的排量下,能夠擁有着更好的燃油效率。
在ggplot2中,不僅僅可以使用顏色進行分組,還可以使用形狀(shape)、透明度(alpha)、大小(size)進行分組。當然,在某些情況下,某種分組的效果不一定合適。在ggplot2中,一次只能使用最多六種形狀(shape),所以在用形狀進行分組的時候,會遇到下面的情況:
ggplot(mpg,mapping = aes(x=displ,y=hwy,shape = class))+
geom_point()
Warning messages:
1: The shape palette can deal with a maximum of 6 discrete values
because more than 6 becomes difficult to discriminate; you have
7. Consider specifying shapes manually if you must have them.
2: Removed 62 rows containing missing values (geom_point).
這時候,Suv不再顯示。
選擇子集
有時候,我們不想看所有的數據,只想看看SUV這一個車型不同排量和燃油效率的關係。那麼應該如何進行繪圖呢?
ggplot(data = mpg,mapping = aes(x=displ,y=hwy))+
geom_point(data = filter(mpg,class == "suv"))
備註:在使用filter()
函數時,需要載入dplyr包,不然會報錯。
除了這種單一的提取出不同子集的方法外,我們還可以使用分面(Facets)將所有的子集繪製出來。
ggplot(data = mpg,mapping = aes(x=displ,y=hwy))+
geom_point()+
facet_wrap(~class,nrow = 2)
使用的函數facet_warp()
需要添加一個公式型的參數,這是R中的一種數據結構形式,而不是指數學上的等式。這種表達方法在進行迴歸分析的時候經常會被使用。
這部分,我們查看了如何在ggplot2中初步探索兩個變量之間的關係,如何繪製散點圖,並且添加光滑曲線,如何用不同的形式表達不同的子集,如何繪製其中的一個子集,如何使用分面在一個圖形中繪製不同的子集。接下來,我們將要探討的是條形圖在ggplot2中應該如何繪製。