"一張統計圖形就是從數據到幾何對象(geometric object, 縮寫為geom, 包括點、線、條形等)的圖形屬性(aesthetic attributes, 縮寫為aes, 包括顏色、形狀、大小等)的一個映射。此外, 圖形中還可能包含數據的統計變換(statistical transformation, 縮寫為stats), 最後繪製在某個特定的坐標系(coordinate system, 縮寫為coord)中, 而分面(facet, 指將繪圖窗口劃分為若干個子窗口)則可以用來生成數據中不同子集的圖形。"
Hadley Wickham
ggplot2是由Hadley Wickham創建的一個十分強大的可視化R包。按照ggplot2的繪圖理念,Plot(圖)= data(數據集)+ Aesthetics(美學映射)+ Geometry(幾何對象)。本文將從ggplot2的八大基本要素逐步介紹這個強大的R可視化包。
數據(Data)和映射(Mapping)
幾何對象(Geometric)
標尺(Scale)
統計變換(Statistics)
坐標系統(Coordinante)
圖層(Layer)
分面(Facet)
主題(Theme)
二 數據(data) 和 映射(Mapping)數據:用於繪製圖形的數據,本文主要使用經典的mtcars數據集和diamonds數據集子集為例來畫圖。
#install.packages("ggplot2")
library(ggplot2)
data(diamonds)
set.seed(1234)
diamond <- diamonds[sample(nrow(diamonds), 2000), ]
head(diamond)
# A tibble: 6 x 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 0.91 Ideal G SI2 61.6 56 3985 6.24 6.22 3.84
2 0.43 Premium D SI1 60.1 58 830 4.89 4.93 2.95
3 0.32 Ideal D VS2 61.5 55 808 4.43 4.45 2.73
4 0.33 Ideal G SI2 61.7 55 463 4.46 4.48 2.76
5 0.7 Good H SI1 64.2 58 1771 5.59 5.62 3.6
6 0.33 Ideal G VVS1 61.8 55 868 4.42 4.45 2.74
映射:aes()函數是ggplot2中的映射函數, 所謂的映射即為數據集中的數據關聯到相應的圖形屬性過程中一種對應關係, 圖形的顏色,形狀,分組等都可以通過通過數據集中的變量映射。
#使用diamonds的數據子集作為繪圖數據,克拉(carat)數為X軸變量,價格(price)為Y軸變量。
p <- ggplot(data = diamond, mapping = aes(x = carat, y = price))#將鑽石的顏色(color)映射顏色屬性:
p <- ggplot(data=diamond, mapping=aes(x=carat, y=price, shape=cut, colour=color))
p+geom_point() #繪製點圖 #將鑽石的切工(cut)映射到形狀屬性:
p <- ggplot(data=diamond, mapping=aes(x=carat, y=price, shape=cut))
p+geom_point() #繪製點圖#將鑽石的切工(cut)映射到分組屬性:
#默認分組設置, 即group=1
p + geom_boxplot()
#分組(group)也是ggplot2種映射關係的一種, 如果需要把觀測點按額外的離散變量進行分組處理, 必須修改默認的分組設置。
p1 <- ggplot(data=diamond, mapping=aes(x=carat, y=price, group=factor(cut)))
p1 + geom_boxplot()注意:不同的幾何對象,要求的屬性會有些不同,這些屬性也可以在幾何對象映射時提供,以下語法與上面的aes中是一樣的。
#結果與上述一致
ggplot(data = diamond)+geom_point(aes(x=carat, y=price, colour=color))
ggplot(data = diamond) +geom_point(aes(x=carat, y=price, shape=cut))
ggplot(data = diamond) +geom_boxplot(aes(x=carat, y=price, group=factor(cut)))
ggplot(data = diamond) +geom_point(aes(x=carat, y=price, colour=color,shape=cut))註:ggplot2支持圖層,可以把不同的圖層中共用的映射提供給ggplot函數,而某一幾何對象才需要的映射參數提供給geom_xxx函數。
三 幾何對象(Geometric)幾何對象代表我們在圖中實際看到的圖形元素,如點、線、多邊形等。數據與映射部分介紹了ggplot函數執行各種屬性映射,只需要添加不同的幾何對象圖層,即可繪製出相應的圖形。
此處介紹幾種常用的幾何對象,geom_histogram用於直方圖,geom_bar用於畫柱狀圖,geom_boxplot用於畫箱式圖等。
直方圖 單變量連續變量:可繪製直方圖展示,提供一個連續變量,畫出數據的分布。
#以價格(price)變量為例,且按照不同的切工填充顏色
ggplot(diamond)+geom_histogram(aes(x=price, fill=cut))#設置position="dodge",side-by-side地畫直方圖
ggplot(diamond)+geom_histogram(aes(x=price, fill=cut), position="dodge")#設置使用position="fill",按相對比例畫直方圖
ggplot(diamond)+geom_histogram(aes(x=price, fill=cut), position="fill")
柱狀圖單變量分類變量:可使用柱狀圖展示,提供一個x分類變量,畫出數據的分布。
#以透明度(clarity)變量為例,且按照不同的切工填充顏色,柱子的高度即為此分類下的數目。
ggplot(diamond)+geom_bar(aes(x=clarity, fill=cut))
註:ggplot2會通過x變量自動計算各個分類的數目。
#直接指定個數,需要通過stat參數,指定geom_bar按特定高度畫圖
ggplot()+geom_bar(aes(x=c(LETTERS[1:5]),y=1:5), stat="identity")
區分與聯繫:
直方圖把連續型的數據按照一個個等長的分區(bin)切分,然後計數畫柱形圖。
柱狀圖是把分類數據,按類別計數。
箱式圖箱線圖通過繪製觀測數據的五數總括,即最小值、下四分位數、中位數、上四分位數以及最大值,描述了變量值的分布情況。同時箱線圖能夠顯示出離群點(outlier),通過箱線圖能夠很容易識別出數據中的異常值。
#按切工(cut)分類,對價格(price)變量畫箱式圖,再按照color變量分別填充顏色。
ggplot(diamond,aes(x=cut, y=price,fill=color))+geom_boxplot()
ggplot(diamond)+geom_boxplot(aes(x=cut, y=price,fill=color))
以上可見,通過映射和幾何對象就可以將數據集中的變量數值變成幾何圖形以及幾何圖形的各種圖形元素。
註:每一種幾何對象所能涉及的aes()類型有區別,在繪製對應對象的時候,要注意選擇正確的映射方式,以下僅供參考:
geomstataesgeom_ablineabinecolour,linetype,sizegeom_areaidentitycolour,fill,linetype,size,x,ygeom_barbincolour,fill,linetype,size,weight,xgeom_bin2dbin2dcolour,fill,linetype,size,weight,xmax,xmin,ymax,ymingeom_blankidentity
geom_boxplotboxplotcolour,fill,lower,middle,size,upper,weight,x,ymax.ymingeom_contourcontourcolour,linetype,size,weight,xgeom_crossbaridentitycolour,fill,linetype,size,x,y,ymax,ymingeom_densitydensitycolour,fill,linetype,size,weight,x,ygeom_density2ddensity2dcolour,linetype,size,weight,x,ygeom_dotplotbindotcolour,fill,x,ygeom_errorbaridentitycolour,linetype,size,width,x,ymax,ymingeom_errorbarhidentitycolour,linetype,size,width,x,ymax,ymingeom_freqpolybincolour,linetype,sizegeom_hexbinhexcolour,fill,size,x,ygeom_histogrambincolour,fill,linetype,size,weight,xgeom_hlinehlinecolour,linetype,sizegeom_jitteridentitycolour,fill,shape,size,x,ygeom_lineidentitycolour,linetype,size,x,ygeom_linerangeidentitycolour,linetype,size,size,x,ymax,ymingeom_mapidentitycolour,fill,linetype,size,x,y,map_idgeom_pathidentitycolour,linetype,size,x,ygeom_pointidentitycolour,fill,shape,size,x,ygeom_pointrangeidentitycolour,fill,linetype,shape,size,x,ymax,ymingeom_polygonidentitycolour,fill,linetype,size,x,ygeom_quantilequantilecolour,linetype,size,weight,x,ygeom_rasteridentitycolour,fill,linetype,size,x,ygeom_rectidentitycolour,fill,linetype,size,xmax,xmin,ymax,ymingeom_ribbonidentitycolour,fill,linetype,size,x,ymax,ymingeom_rugidentitycolour,linetype,sizegeom_segmentidentitycolour,linetype,size,x,xend.y.yendgeom_smoothsmoothaplha,colour,fill,linetype,size,weight,x,ygeom_stepidentitycolour,linetype,size,x,ygeom_textidentityangle,colour,hjust,label,size,size,vjust,x,ygeom_tileidentitycolour,fill,linetype,size,x,ygeom_violinydensityweigth,colour,fill,size,linetype,x,ygeom_vlinevlinecolour,linetype,size
四、標尺(Scale)在對圖形屬性進行映射之後,使用標尺可以控制這些屬性的顯示方式,比如坐標刻度,顏色屬性等。
ggplot2的scale系列函數有很多,命名和用法是有一定規律的。一般使用三個單詞用_連接,如scale_fill_gradient和 scale_x_continuous,
此處僅介紹顏色設置和坐標軸設置函數的一些用法,其他類似。
1 顏色標尺設置(color fill)1.1 顏色標尺「第二個」單詞選擇方法顏色的函數名第二個單詞有color和fill兩個,對應分組使用的顏色函數即可。
比如柱狀圖,fill是柱子的填充顏色,這時就使用scale_fill系列函數來更改顏色。
比如點圖使用color分組,則使用scale_color_系列函數來更改顏色。
1.2 顏色標尺「第三個」單詞選擇方法根據第三個單詞的不同,更換的顏色分為以下幾種
1)離散型:在顏色變量是離散變量的時候使用,比如分類時每一類對應一種顏色
2)連續型:顏色變量是連續變量的時候使用,比如0-100的數,數值越大顏色越深這樣
1.3 更改離散型變量的顏色函數#數據,映射以及幾何對象
p <- ggplot(diamond, aes(color))+geom_bar(aes(fill=cut)) #左上manual 直接指定分組使用的顏色
#values參數指定顏色
#直接指定顏色 (右上)
p + scale_fill_manual(values=c("red", "blue", "green","yellow","orange"))
#對應分組指定 (左下)
p + scale_fill_manual(values=c("Fair" = "red", "Good" = "blue", "Very Good" = "green" , Premium = "orange", Ideal = "yellow"))
#更改圖例名字,對應指定並更改圖例標籤 (右下)
p + scale_fill_manual("class", values=c("red", "blue", "green","yellow","orange"),
breaks = c("Fair", "Good", "Very Good","Premium","Ideal"),
labels = c("一般", "好", "很好", "高級", "理想"))
brewer 使用ColorBrewer的顏色
#palette參數調用色板
library(RColorBrewer)
#主要是palette參數調用色板
p + scale_fill_brewer() # 默認使用Blues調色板中的顏色(左)
p + scale_fill_brewer(palette = "Greens") #使用Greens調色板中的顏色 (右)
p + scale_fill_brewer(palette = "Greens",direction = -1)
grey 使用不同程度的灰色
#通過start end 兩個參數指定,0為黑,1為白,都在0-1範圍內
p + scale_fill_grey() # 左圖
#設定灰度範圍
p + scale_fill_grey(start=1, end=0) # 右圖
p + scale_fill_grey(start=1, end=0.5)
1.4 更改連續型變量的顏色函數
#構建數據集
df <- data.frame(
x = runif(100),
y = runif(100),
z1 = rnorm(100)
)
p <- ggplot(df, aes(x, y)) + geom_point(aes(colour = z1))
gradient 創建漸變色#參數設定節點顏色
#設置兩端顏色
p + scale_color_gradient(low = "white", high = "black")
#設置中間過渡色
p + scale_color_gradient2(low = "red", mid = "white", high = "blue")
#使用R預設調色板
p + scale_color_gradientn(colours =rainbow(10))
#legeng展示指定標籤
p + scale_color_gradient(low = "white", high = "black",
breaks=c(1,2,0.5),
labels=c("a","b","c"))
#legend名稱
p + scale_color_gradient("black", low = "white", high = "black",
limits=c(0.5,2))
distiller 使用ColorBrewer的顏色
#將ColorBrewer的顏色應用到連續變量上
p + scale_color_distiller(palette = "Spectral")
p + scale_color_distiller(palette = "Greens")
2 坐標軸標尺修改(x , y)本部分主要是對坐標軸做如下改變,
更改坐標軸名稱
更改x軸上標數的位置和內容
顯示對一個軸做統計變換
只展示一個區域內的點
更改刻度標籤的位置
實現上面的這些可以使用scale_x等函數,同時像xlab這樣的函數實現其中某一方面的功能,但是用起來更加方便
因為這裡的數據也有連續和離散之分,所以也要使用不同的函數來實現。
# 橫坐標是離散變量,縱坐標是連續變量
p <- ggplot(mtcars, aes(factor(cyl), mpg)) + geom_point()
# 更改坐標軸名稱
p + scale_x_discrete("cyl")
# 更改橫軸標度
p + scale_x_discrete(labels = c("4"="a","6"="b","8"="c"))
# 指定橫軸順序以及展示部分
p + scale_x_discrete(limits=c("6","4"))
# 連續變量可以更改標度(圖與上相似,略)
p + scale_y_continuous("ylab_mpg")
p + scale_y_continuous(breaks = c(10,20,30))
p + scale_y_continuous(breaks = c(10,20,30), labels=scales::dollar)
p + scale_y_continuous(limits = c(10,30))
# 連續變量可以更改標度,還可以進行統計變換
p + scale_y_reverse() # 縱坐標翻轉,小數在上面,大數在下面
p + scale_y_log10()
p + scale_y_continuous(trans = "log10")
p + scale_y_sqrt()# 更改刻度標籤的位置p + scale_x_discrete(position = "top") +
scale_y_continuous(position = "right")註:除使用scale參數進行設置外,後面會介紹使用更簡單易用的函數。
五 統計變換(Statistics)ggplot2提供了多種統計變換方式,此處介紹兩種較常用的。
1 stat_summary要求數據源的y能夠被分組,每組不止一個元素, 或增加一個分組映射,即aes(x= , y = , group = )
library(Hmisc)
g <- ggplot(mtcars,aes(cyl, mpg)) + geom_point()
#mean_cl_bool對mpg進行運算,返回均值,最大值,最小值;其他可用smean.cl.normal,smean.sdl,smedian.hilow。
g + stat_summary(fun.data = "mean_cl_boot", color = "red", size = 2)#fun.y 對y的匯總函數,返回單個數字,y通常會被分組匯總後每組返回1個數字
g + stat_summary(fun.y = "mean", color = "red", size = 2, geom = "point") # 計算各組均值# 增加1組顏色變量映射,然後求均值並連線
g + aes(color = factor(vs)) + stat_summary(fun.y = mean, geom = "line") #fun.ymax 表示取y的最大值,輸入數字向量,每組返回1個數字
g + stat_summary(fun.y = mean, fun.ymin = min, fun.ymax = max, color = "red") # 計算各組均值,最值
2 stat_smooth對原始數據進行某種統計變換計算,然後在圖上表示出來,例如對散點圖上加一條回歸線。
#添加默認曲線
#method 表示指定平滑曲線的統計函數,如lm線性回歸, glm廣義線性回歸, loess多項式回歸, gam廣義相加模型(mgcv包), rlm穩健回歸(MASS包)
ggplot(mpg, aes(displ, hwy)) +geom_point() +stat_smooth()
ggplot(mpg, aes(displ, hwy)) +geom_point() +geom_smooth() +stat_smooth(method = lm, se = TRUE)
#formula 表示指定平滑曲線的方程,如 y~x, y~poly(x, 2), y~log(2) ,需要與method參數搭配使用
ggplot(mpg, aes(displ, hwy)) +geom_point() +stat_smooth(method = lm, formula = y ~ splines::bs(x, 3), se = FALSE)#se 表示是否顯示平滑曲線的置信區間,默認TRUE顯示;level = 0.95
ggplot(mpg, aes(displ, hwy, color = class)) + geom_point() + stat_smooth(se = FALSE, method = lm)註:以下為ggplot2提供的其他統計變換方式,也可以自己寫函數基於原始數據進行計算。
stat_abline stat_contour stat_identity stat_summary
stat_bin stat_density stat_qq stat_summary2d
stat_bin2d stat_density2d stat_quantile stat_summary_hex
stat_bindot stat_ecdf stat_smooth stat_unique
stat_binhex stat_function stat_spoke stat_vline
stat_boxplot stat_hline stat_sum stat_ydensity
六 坐標系統(Coordinante) 坐標系統控制坐標軸,可以進行變換,例如XY軸翻轉,笛卡爾坐標和極坐標轉換,以滿足我們的各種需求。
1 coord_flip()實現坐標軸翻轉ggplot(diamond)+geom_bar(aes(x=cut, fill=cut))+coord_flip()
2 coord_polar()實現極坐標轉換#靶心圖
ggplot(diamond)+geom_bar(aes(x=factor(1), fill=cut))+coord_polar()
#餅圖
ggplot(diamond)+geom_bar(aes(x=factor(1), fill=cut))+coord_polar(theta="y")
#風玫瑰圖(windrose)
ggplot(diamond)+geom_bar(aes(x=clarity, fill=cut))+coord_polar()七 圖層(Layer)ggplot的強大之處在於直接使用+號即可實現疊加圖層,前面散點圖添加擬合曲線即為圖層疊加。
ggplot(mpg, aes(displ, hwy)) +geom_point() +geom_smooth() +stat_smooth(method = lm, se = TRUE)ggplot函數可以設置數據和映射,每個圖層設置函數(geom_xxx和stat_xxx)也都可以設置數據和映射,這雖然便利,但也可能產生一些混亂。
ggplot2的圖層設置函數對映射的數據類型是有較嚴格要求的,比如geom_point和geom_line函數要求x映射的數據類型為數值向量,而geom_bar函數要使用因子型數據。如果數據類型不符合映射要求就得做類型轉換,在組合圖形時還得注意圖層的先後順序。
八 分面(Facet)分面設置在ggplot2應該也是要經常用到的一項畫圖內容,在數據對比以及分類顯示上有著極為重要的作用,
facet_wrap 和 facet_grid是兩個經常要用到的分面函數。
1 facet_wrap:基於一個因子進行設置,形式為:~變量(~單元格)
#cyl變量進行分面
p<-ggplot(mtcars,aes(mpg,hp))+geom_point()
p+facet_wrap(~cyl)
#每個分面單獨的坐標刻度,單獨對x軸設置
#scales參數fixed表示固定坐標軸刻度,free表示反饋坐標軸刻度,也可以單獨設置成free_x或free_y
p+facet_wrap(~cyl,scales="free")
#每個分面單獨的坐標刻度,單獨對y軸設置
#nrow,ncol參數為數值,表示 分面設置成幾行和幾列
p+facet_wrap(~carb,scales="free",nrow=1)
對nrow設置後的效果圖表變得比較擁擠,正常情況下,facet_wrap自然生成的圖片,只設置scale = free 會相對比較好看。
2 facet_grid:基於兩個因子進行設置,形式為:變量~變量(行~列),如果把一個因子用點表示,也可以達到facet_wrap的效果,也可以用加號設置成兩個以上變量
p+facet_grid(vs~cyl)
#space 表示分面空間是否可以按照數據進行縮放,參數和scales一樣
p+facet_grid(vs~cyl,scales="free",space="free")
從上圖可以看出把scales 和space 都設置成free之後,不僅坐標刻度不一樣了,連每個分面的大小也不一樣了。
#margins 通過TRUE或者FALSE表示否設置而一個總和的分面變量,默認情況為FALSE,即不設置
p+facet_grid(vs~cyl,margins=TRUE)分面可以讓我們按照某種給定的條件,對數據進行分組,然後分別畫圖。
九 主題(Theme)ggplot畫圖之後,需要根據需求對圖進行」精雕細琢「,title, xlab, ylab毋庸置疑,其他的細節也需修改。
1 theme參數修改詳細參數可參考:ggplot2-theme(主題)
p <- ggplot(data = diamond) +geom_point(aes(x=carat, y=price, colour=color,shape=cut))
p + labs(title="學習ggplot2可視化",subtitle = "參數好多",caption = "熟能生巧")+
theme(plot.title=element_text(face="bold.italic",color="steelblue",size=24, hjust=0.5,vjust=0.5,angle=360,lineheight=113))
下面為theme的相關參數,可以細節修改處,之後的後面會繼續補充。
function (base_size = 12, base_family = "")
{
theme(line = element_line(colour = "black", size = 0.5, linetype = 1,
lineend = "butt"), rect = element_rect(fill = "white",
colour = "black", size = 0.5, linetype = 1), text = element_text(family = base_family,
face = "plain", colour = "black", size = base_size, hjust = 0.5,
vjust = 0.5, angle = 0, lineheight = 0.9), axis.text = element_text(size = rel(0.8),
colour = "grey50"), strip.text = element_text(size = rel(0.8)),
axis.line = element_blank(), axis.text.x = element_text(vjust = 1),
axis.text.y = element_text(hjust = 1), axis.ticks = element_line(colour = "grey50"),
axis.title.x = element_text(), axis.title.y = element_text(angle = 90),
axis.ticks.length = unit(0.15, "cm"), axis.ticks.margin = unit(0.1,
"cm"), legend.background = element_rect(colour = NA),
legend.margin = unit(0.2, "cm"), legend.key = element_rect(fill = "grey95",
colour = "white"), legend.key.size = unit(1.2, "lines"),
legend.key.height = NULL, legend.key.width = NULL, legend.text = element_text(size = rel(0.8)),
legend.text.align = NULL, legend.title = element_text(size = rel(0.8),
face = "bold", hjust = 0), legend.title.align = NULL,
legend.position = "right", legend.direction = NULL, legend.justification = "center",
legend.box = NULL, panel.background = element_rect(fill = "grey90",
colour = NA), panel.border = element_blank(), panel.grid.major = element_line(colour = "white"),
panel.grid.minor = element_line(colour = "grey95", size = 0.25),
panel.margin = unit(0.25, "lines"), strip.background = element_rect(fill = "grey80",
colour = NA), strip.text.x = element_text(), strip.text.y = element_text(angle = -90),
plot.background = element_rect(colour = "white"), plot.title = element_text(size = rel(1.2)),
plot.margin = unit(c(1, 1, 0.5, 0.5), "lines"), complete = TRUE)
}
2 ggplot2 默認主題除此外,ggplot2提供一些已經寫好的主題,比如theme_grey()為默認主題,theme_bw()為白色背景主題,theme_classic()為經典主題。
p + theme_classic()
3 ggplot2 擴展包主題
library(ggthemes)
p + theme_stata()
除上述外,ggthemes包還提供其他主題,小夥伴們自己嘗試吧。
theme_economist theme_economist_white
theme_wsj theme_excel
theme_few theme_foundation
theme_igray theme_solarized
theme_stata theme_tufte
4 自定義主題可根據常見需要自定義常用主題
theme_MJ <- function(..., bg='white'){
require(grid)
theme_classic(...) +
theme(rect=element_rect(fill=bg),
plot.margin=unit(rep(1,4), 'lines'),
panel.border=element_rect(fill='transparent', color='transparent'),
panel.grid=element_blank(),
axis.title = element_text(color='black', vjust=0.1),
axis.ticks.length = unit(-0.1,"lines"),
axis.ticks = element_line(color='black'),
legend.title=element_blank(),
legend.key=element_rect(fill='transparent', color='transparent'))
}
p + theme_MJ() + labs(title="學習ggplot2可視化",subtitle = "參數好多記不住?",caption = "熟能生巧!")以上就是ggplot2的八大要素,七顆龍珠可召喚神龍,八大要素合理使用可畫出「神龍」,🤭!!!
百度搜索 ImageGP,輕鬆在線繪圖
50個ggplot2可視化案例
ggplot2高效實用指南 (可視化腳本、工具、套路、配色)
用了都說好的SCI在線繪圖工具來了~~~~~~~
往期精品(點擊圖片直達文字對應教程)後臺回復「生信寶典福利第一波」或點擊閱讀原文獲取教程合集