在R語言裡,談及繪圖,ggplot2是最出名的繪圖包之一,作為一個繪圖神器,它提供了許許多多的功能給用戶使用,僅用短短幾行代碼,一幅幅高端大氣的圖像便躍然紙上,這可能就是ggplot2包的魅力所在。
我剛開始學習ggplot2的時候只用於學術上的製圖,對深層的製圖一知半解,趁著有空便重新學習了一下ggplot2包,才發現其背後的製圖邏輯竟然跟GIS的圖層疊加有著高度的相似,下面就是我學習到的內容了。
這次使用的數據集是R包內置的iris數據集,是由Edgar Anderson記錄的3種鳶尾花形態數據。其中一個種類與另外兩個種類是線性可分離的,後兩個種類是非線性可分離的。
iris以鳶尾花的特徵作為數據來源,常用在分類操作中。該數據集由3種不同類型的鳶尾花的各50個樣本數據構成。其中的一個種類與另外兩個種類是線性可分離的,後兩個種類是非線性可分離的。
該數據集包含了4個屬性:
①Sepal.Length(花萼長度),單位是cm;
②Sepal.Width(花萼寬度),單位是cm;
③Petal.Length(花瓣長度),單位是cm;
④Petal.Width(花瓣寬度),單位是cm;
⑤Species(種類):Iris Setosa(山鳶尾)、Iris Versicolour(雜色鳶尾),以及Iris Virginica(維吉尼亞鳶尾)。
我們用相同的數據,通過plot函數跟ggplot函數分別繪製散點圖來簡單理解一下兩者的差異:
library("ggplot2") #加載安裝好的ggplot2包plot(iris$Sepal.Length, iris$Sepal.Width) #plot繪圖ggplot(data = iris,aes(x = Sepal.Length, #ggplot2繪圖 y=Sepal.Width))+ #繪製底層畫布 geom_point(color = "darkred") #在畫布上添加點從上述代碼可以看出,ggplot繪圖有以下兩個特點:
(1)有明確的開始(以ggplot函數開始)與終止(一條語句一幅畫) ;
(2)ggplot2語句可以理解成一條語句一幅畫,然後通過圖層疊加,疊加通過「+」號將繪圖的語句連接起來。
上面介紹的ggplot2繪圖有明確的開始,即以ggplot函數作為開始的標誌,那麼ggplot()有什麼用呢?
它的主要功能在於初始化一個ggplot對象,且不指定繪圖內容,格式如下:
ggplot(data = NULL, mapping = aes(), ...,environment = parent.frame())其中,data指的要繪圖的數據集,它會被制定為繪圖環境,載入之後就不需要寫大量的$符號來提取data.frame裡面的向量的操作。如果數據都是向量,那麼也可不指定,但要在聲明中標註data=NULL,否則會有不必要的報錯。
數據與圖形屬性之間的映射關係稱mapping。
ggplot對象的data存儲了整個屬性框的內容,而mapping則確定如何使用這些數據。圖形的可視屬性包括如形狀、顏色、透明度等美學屬性,確定美學屬性與數據之間的對應關係一般用aes函數。常見的圖形屬性包括x、y、size、color、group.
比如,當data=iris時,mapping= aes(x = Sepal.Length, y = Sepal.Width)表示將花 萼長度作為x軸變量,將花萼寬度作為y軸變量。如果需要將Species映射到形狀或者顏色屬性,可以添加shape=Species或者colour = Species. 使用ggplot函數繪製底層畫布
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, colour = Species, shape = Species))除了數據與映射之外,一個圖層還應該至少包含位置、stat、position這三個圖形屬性。
幾何對象簡單來說就是採用展示數據的圖形類型。
如散點圖、條形圖等,ggplot2包提供了許多的圖形類型供用戶使用。
描述
幾何對象函數
描述
geom_abline
線,由斜率和截距指定
geom_jitter
點,自動添加了擾動
geom_area
面積圖
geom_line
線
geom_bar
條形圖
geom_path
幾何路徑
geom_bin2d
二維封箱的熱圖
geom_point
點
geom_blank
空的幾何對象,什麼都不畫
geom_pointrange
一條垂直線,線中間有一個點
geom_boxplot
箱線圖
geom_polygon
多邊形
geom_contour
等高線圖
geom_quantile
一組分位數線
geom_crossbar
類似於箱線圖,但無觸鬚和極值點
geom_rect
二維長方形
geom_density
密度圖
geom_ribbon
彩虹圖
geom_density2d
二維密度圖
geom_rug
觸鬚
geom_errorbar
誤差線
geom_segment
線段
geom_errorbarh
水平誤差線
geom_smooth
平滑的條件均值
geom_freqploy
頻率多邊形
geom_step
階梯圖
geom_hex
六邊形圖
geom_text
文本
geom_histogram
直方圖
geom_tile
瓦片
geom_hline
水平線
如果要在畫布上繪製散點圖的話,則只需在「+」號後面添加函數geom_point即可:ggplot(data = iris)+ #繪製底層畫布geom_point(aes(x = Sepal.Length, y = Sepal,Width, colour = Species, shape = Species))統計類型stat是指對數據所應用的統計類型和方法。
上述代碼中沒有指定統計類型,但自動獲得identity,因為ggplot2會默認為每一種幾何類型都指定一種默認的統計類型,反之亦然。其中stat_identity表示不做任何的統計變換。運行代碼如下:
ggplot(iris)+ geom_bar(aes(x = Sepal.Length, stat = "bin", binwidth = 0.5))aes函數設定了數據與圖形屬性的映射關係,但是數據怎麼映射為屬性則是標尺(Scale) 的功能。
對於任何一個圖形屬性,如x,y,alpha,color,fill,linetype,shape,size等,ggplot2都提供以下4種標尺:
(1)scale_*_continuous:將數據的連續取值映射為圖形屬性的取值
(2)scale_*_discrete:將數據的離散取值映射為圖形屬性的取值
(3)scale_*_identity:將數據的值作為圖形屬性的取值
(4)scale_*_mannual:將數據的離散取值作為手工指定的圖形屬性的取值
隨機從iris數據集的150個樣本中抽取100個樣本,並繪製條形圖以反映100個樣本中各個鳶尾花,並繪製條形圖以反映100個樣本中各個鳶尾花種類的數量情況,然後提供修改標尺參數做前後對比圖。代碼如下:
set.seed(1234)my_iris <- iris[sample(1:150,100,repleace = FALSE)]p <- ggplot(my_iris) + geom_bar(aes(x = Species,fill = Species))p #修改標尺參數前的圖形p <- p +scale_fill_manual( values = c("orange","olivedrab","navy") #顏色設置 breaks = c("setosa","versicolor","virginica") #圖例和軸要顯示的分段點 name = "my_Species", #圖例和軸使用的名稱 labels = c("set","ver","vir") #修改標尺參數後的圖)可以使用scale_color_manual函數或scale_color_brewer函數修改圖形的顏色。比如對iris數據集中的Sepal.Length與Sepal.Width的散點圖分別使用scale_color_manual函數或scale_color_brewer函數修改圖形顏色,代碼如下:
#圖一:使用scale_color_manual函數ggplot(iris,aes(x = Sepal.Length, y = Sepal.Width, colour = Species))+ scale_color_manual(values = c("orange","olivedrab","navy"))+ geom_point(size = 2)#圖二:使用scale_color_brewer函數ggplot(iris,aes(x = Sepal.Length, y = Sepal.Width, colour = Species))+ scale_color_brewer(palette = "Set1") + geom_point(size = 2)使用scale_color_manual函數修改顏色
使用scale_color_brewer函數修改顏色
ggplot2默認的坐標系是笛卡爾坐標系
(1)可以使用以下方法指定坐標系的取值範圍coord_cartesian(xlim = c(0,5),ylim = c(0.3))。
(2)如果要讓x軸跟y軸交換位置,則可以使用coord_flip函數。
(3)如果要使用角度坐標系,可以使用以下方法進行轉換:coord_polar(theta = "x",start =0,direction = 1) ,這裡theta指定角度對應的變量,start指定離12點鐘方向的偏離值若direction = 1,則表示順時針方向;若direction = -1,則表示逆時針方向。
# 1.餅狀圖 = 堆疊長條圖+角度坐標系pie <-ggplot(my_iris,aes(x = factor(1), fill = Species))+ geom_bar(width = 1) #堆疊長條圖pie + coord_polar(theta = "y")
# 2. 靶心圖 = 餅狀圖 + polar coordinatespie + coord_polar()
#3. 鋸齒圖 = 柱狀圖 + polar coordinatescxc = ggplot(my_iris,aes(x = Species))+ geom_bar(width = 1, colour = "black")cxc+coord_polar()分面就是分組繪圖,即根據定義的規則將數據分為多個子集,每個子集按照一定的規則單獨繪圖,排布在一個頁面上。ggplot2提供兩種分面函數:facet_grid函數和facet_wrap函數。
gather(data,key,value,...,na.rm = FALSE,convert =FALSE,factor_key =FALSE)這裡,facet_grid函數是一個二維的矩形布局,每個自己的位置由行位置變量和列位置變量控制。下面以Species的取值作為一列,將feature_name的取值作為一行作為示例:
library(ggplot2)library(tidyr)library(dplyr)my_iris1 <-iris %>% gather(feature_name, feature_value, one_of(c("Sepal.Length", "Sepal.Width", "Petal.Length", "Petal.Width"))) #數據變換ggplot(my_iris1)+ geom_violin(aes(x = Species, y = feature_value))+ #繪製小提琴圖 facet_grid(feature_name ~ Species, scales = "free") #分面facet_wrap函數會生成一個動態調整的一維布局,根據「~位置變量1+位置變量2+...」來確定每個子集的位置,先逐行排列,放不下了再移到下一行。以my_iris1數據集作為例子,操作代碼如下:
ggplot(my_iris1)+ geom_violin(aes(x = Species, y = feature_value))+ facet_wrap(~feature_name + Species, scales = "free")ggplot2包提供了ggsave函數進行圖形保存
格式如下:
ggsave(filename,width,height,...)其中,filename為保存的文件名和路徑,width為圖像寬度,height為圖像高度,例如在當前工作目錄下生成一個名為「test」的PDF圖形,代碼如下:
ggplot(iris,aes(x = Sepal.Length, y = Sepal.Width, colour = Species))+ geom_point(size = 2)ggsave(file = "test.pdf", width = 2, height = 4)ggplot2包的繪圖邏輯介紹到這裡了,當然還有很多很多其他東西,這裡就不一一贅述了,想學習更多的可以在某度或者查看幫助文檔喔。學無止境,披荊前行!