以三個數據集解釋ggplot2
的使用。第一個是lattice
包中的singer
數據集,它包括紐約合唱團歌手的高度和語音變量。第二個是mtcars
數據集,它包含32輛汽車的詳細信息。最后一個是car
包中的Salaries
數據集,它包含大學教授的收入信息,并用來探索性別差異對它們收入的影響。這些數據集提供了各種可視化的挑戰。
ggplot2包介紹
在ggplot2中,圖是采用串聯起來(+)號函數創建的。每個函數修改屬于自己的部分。也就是說,每個函數完成圖中各個組件的相應功能,然后通過串聯+號將其連接起來,形成一個完整的圖形。
> library(ggplot2)
> ggplot(data=mtcars, aes(x=wt, y=mpg)) +
+ geom_point() +
+ labs(title="Automobie Data", x="Weight", y="Miles Per Gallon")
分解上述圖形的制作步驟:
? ggplot()
初始化圖形并指定要用到的數據來源和變量。aes()
函數的功能是指定每個變量扮演的角色(aes代表aesthetics,即如何用視覺形式呈現信息)。在這里,變量wt
的值映射到x軸,mpg
的值映射到y軸。
? ggplot
函數設置圖形但沒有自己的視覺輸出。使用一個或多個幾何函數向圖中添加了幾何對象(簡寫為geom),包括點、線、條、箱線圖和陰影區域。在上述例子中,geom_point()
函數在圖形中畫點,創建了一個散點圖。labs()
函數是可選的,可以添加注釋、軸標簽、標題等。
ggplot2中有很多函數,并且大多數包含可選的參數。下面我們來看一下相應擴展。
> png('Scatter plot 2.png')
> ggplot(data=mtcars, aes(x=wt, y=mpg)) +
+ geom_point(pch=17, color='blue', size=2) +
+ geom_smooth(method='lm', color='red', linetype=2) +
+ labs(title="Automobile Data", x="Weight", y="Miles Per Gallon")
> dev.off()
![Uploading Automobile Data by Engine Type_988673.png . . .]
我們依據對最初圖形的解釋,可以很清晰的觀察到不同的函數執行了什么樣的功能。
ggplot2包提供了分組和小面化的方法。分組指的是在一個圖形中顯示兩組或多組觀察結果。小面化指的是在單獨、并排的圖形上顯示觀察組。需要注意,ggplot2包在定義組或面時使用因子。
這里我們使用mtcars
數據集查看分組和面,并進行繪圖。
# 將變量轉換為因子
mtcars$am <- factor(mtcars$am, levels=c(0,1), labels=c("Automatic", "Manual"))
mtcars$vs <- factor(mtcars$vs, levels=c(0,1), labels=c("V-Engine", "Straight Engine"))
mtcars$cyl <- factor(mtcars$cyl)
library(ggplot2)
# 繪圖
ggplot(data=mtcars, aes(x=hp, y=mpg, shape=cyl, color=cyl)) +
geom_point(size=3) +
facet_grid(am~vs) +
labs(title="Automobile Data by Engine Type", x="Horsepower", y="Miles Per Gallon")
在本例中,am
和vs
是刻度變量,cyl
是分組變量。
用幾何函數指定圖的類型
ggplot()
函數指定要繪制的數據源和變量,幾何函數則指定這些變量如何在視覺上進行表示。目前,有37個幾何函數可供使用。以下列出常用的函數。
函數 | 添加 | 選項 |
---|---|---|
geom_bar() | 條形圖 | color, fill, alpha |
geom_boxplot() | 箱線圖 | color, fill, alpha, notch, width |
geom_density() | 密度圖 | color, fill, alpha, linetype |
geom_histogram() | 直方圖 | color, fill, alpha, linetype, binwidth |
geom_hline() | 水平線 | color, aplha, linetype, size |
geom_jitter() | 抖動點 | color, size, alpha, shape |
geom_line() | 線圖 | colorvalpha, linetype, size |
geom_point() | 散點圖 | color, alpha, shape, size |
geom_rug() | 地毯圖 | color, sides |
geom_smooth() | 擬合曲線 | method, formula, color, fill, linetype, size |
geom_text() | 文字注解 | 這個非常多,參考相應文檔 |
geom_violin() | 小提琴圖 | color, fill, alpha, linetype |
geom_vline() | 垂線 | color, alpha, linetype, size |
關于幾何函數的常見選項
選項 | 詳述 |
---|---|
color | 對點、線和填充區域的邊界進行著色 |
fill | 對填充區域著色,如條形和密度區域 |
alpha | 顏色的透明度,從0(完全透明)到1(不透明) |
linetype | 圖案的線條(1=實線,2=虛線,3=點,4=點破折號,5=長破折號,6=雙破折號) |
size | 點的尺寸和線的寬度 |
shape | 點的形狀(和pch一樣,0=開放的方形,1=開放的圓形,2=開放的三角形,等等) |
position | 繪制諸如條形圖和點等對象的位置。對條形圖來說,'dodge'將分組條形圖并排,'stacked'堆疊分組條形圖,'fill'垂直地堆疊分組條形圖并規范其高度相等。對于點來說,'jitter'減少點重疊。 |
binwidth | 直方圖的寬度 |
notch | 表示方塊圖是否應為缺口(TRUE/FALSE) |
sides | 地毯圖的安置("b"=底部, "l"=左部,"t"=頂部,"r"=右部,"bl"=左下部,等等) |
width | 箱線圖的寬度 |
下面舉個例子來驗證一下以上參數的使用:
data(Salaries, package='car')
library(ggplot2)
ggplot(Salaries, aes(x=rank, y=salary)) +
geom_boxplot(fill="cornflowerblue",
color="black", notch = TRUE) +
geom_point(position='jitter', color='blue', alpha=0.5) +
geom_rug(sides='l', color='black')
該圖顯示了不同學術地位對應薪水的缺口箱線圖。實際的觀察值(教師)是重疊的,因而給予一定的透明度以避免遮擋箱線圖。它們還抖動以減少重疊。最后,一個地毯圖設置在左側以指示薪水的一般擴散。
當幾何函數組合形成新類型的圖時,ggplot2
包的真正力量就會得到展示,讓我們利用singer
數據集再來一探究竟。
library(ggplot2)
data(singer, package = "lattice")
ggplot(singer, aes(x=voice.part, y=height)) +
geom_violin(fill="lightblue") +
geom_boxplot(fill="lightgreen", width=.2)
箱線圖展示了在singer
數據框中每個音部的25%,50%,75%分位數得分和任意的異常值。對于每個聲部身高范圍上的得分分布,小提琴圖展示了更多視覺線索。
接下來我們將使用幾何函數創建廣泛的圖表類型。讓我們從分組開始吧——在一個圖中展示多個分組觀察值。
分組
在R中,組通常用分類變量的水平(因子)來定義。
分組是通過ggplot2
圖將一個或多個帶有諸如顏色、形狀、填充、尺寸和線條類型的視覺特征的分組變量來完成的。ggplot()
聲明中的aes()
函數負責分配變量(圖形的視覺特征)。
我們依舊以Salaries
數據集來進行相關探索。
首先,查看薪水是如何隨學術等級變化的:
data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=salary, fill=rank)) +
geom_density(alpha=.3)
接下來,我們通過性別和學術等級分組,繪制獲得博士學位年數和薪水的關系:
ggplot(Salaries, aes(x=yrs.since.phd, y=salary, color=rank, shape=sex)) +
geom_point()
最后,我們可以用一個分組的條形圖按學術等級和性別來可視化教授的人數(三種條形圖方式):
值得注意的是,第三個圖形中y軸的標簽是錯誤的,它應該是比例而不是數量。我們可以通過添加y="proportion"參數到labs()函數來解決。
選項可以通過不同的方式使用,這取決于它們發生在aes()
函數的內部還是外部。通常來說,變量應該設在aes()
函數內,分配常數應該在aes()
函數外。
刻面
如果組在圖中并排出現而不是重疊為單一的圖形,關系就是清晰的。我們可以使用facet_wrap()
函數和facet_grid()
函數創建網格圖形(在ggplot2中也稱為刻面圖)。下表給出了相關的語法,var
,rowvar
,colvar
是因子。
語法 | 結果 |
---|---|
facet_wrap(~var, ncol=n) | 將每個var水平排列成n列的獨立圖 |
facet_wrap(~var, nrow=n) | 排成n行獨立圖 |
facet_grid(rowvar~colvar) | rowvar和colvar組合的獨立圖 |
facet_grid(rowvar~.) | 每個rowvar水平的獨立圖,配置成一個單列 |
facet_grid(.~colvar) | 每個colvar水平的獨立圖,配置成單行 |
3個例子
data(singer, package = 'lattice')
library(ggplot2)
ggplot(data=singer, aes(x=height)) +
geom_histogram() +
facet_wrap(~voice.part, nrow=4)
ggplot(data=singer, aes(x=height)) +
geom_density() +
facet_grid(voice.part~., nrow=4)
data(Salaries, package='car')
library(ggplot2)
ggplot(Salaries, aes(x=yrs.since.phd, y=salary, color=rank, shape=rank))+
geom_point() + facet_grid(.~sex)
添加光滑曲線
這一部分我們著重分析一下添加平滑曲線到散點圖的方法。
我們可以使用geom_smooth()
函數來添加一系列的平滑曲線和置信區域。函數的參數參考下表:
選項 | 描述 |
---|---|
method= | 使用的平滑函數。允許的值包括lm, glm, smooth, rlm, glm,分別對應線性、廣義線性、loess、健壯線和廣義相加模型。smooth是默認值 |
formula= | 在光滑函數中使用的公式。例子包括y~x, y~log(x), y~poly(x,n), y~ns(x) |
se | 繪制置信區間(TRUE/FALSE)默認為TRUE |
level | 使用的置信區間水平(默認為95%) |
fullrange | 指定擬合應涵蓋全圖(TRUE),或僅僅是數據(FALSE)。默認為FALSE |
使用Salaries數據集,忽略性別和學術等級,我們先檢驗博士畢業年數和薪水之間的關系。
data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=yrs.since.phd, y=salary)) +
geom_smooth() + geom_point()
統計函數:
? ggplot2包中含有大量統計函數來計算所需的量,從而生產更多的可視化數據。通常情況下,幾何函數隱式地調用統計函數,我們不需要直接處理這些問題。不過指導它們的存在是有用的。
修改ggplot2圖形的外觀
R的基礎繪圖中,使用par()
函數或特定的畫圖函數的圖形參數來自定義基本函數。遺憾的是,這些對ggplot2圖形沒有影響,該包提供了特定了函數來改變其圖形的外觀。
坐標軸
ggplot2包會自動生成基本所需要的圖形參數。當我們需要更大程度定制時,需要了解相應函數的用法。我們已經知道labs()
函數可以用來添加標題并改變坐標軸標簽,讓我們再看看其他的有用函數:
函數 | 選項 |
---|---|
scale_x_continuous()和scale_y_continuous() | breaks=指定刻度標記、labels=指定刻度標記標簽、limits=控制要展示的值的范圍 |
scale_x_discrete()和scale_y_discrete() | breaks=對因子的水平進行放置和排序,labels=指定這些水平的標簽,limits=表示哪些水平應該展示 |
coord_filp() | 顛倒x軸和y軸 |
我們將這些函數應用一個分組箱線圖中,其中包含按學術等級和性別分組的薪資水平,代碼如下:
data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=rank, y=salary, fill=sex)) +
geom_boxplot() +
scale_x_discrete(breaks=c('AsstProf', 'AssocProf', 'Prof'),
labels=c('Assistant\nProfessor',
"Associate\nProfessor",
"Full\nProfessor")) +
scale_y_continuous(breaks = c(50000, 100000, 150000, 200000),
labels=c('$50K','$100K','$150K','$200K')) +
labs(title="Faculty Salary by Rank and Sex", x='', y='')
圖例
圖例是指如何用顏色、形狀、尺寸等視覺特征表示數據特征的指南。標題和位置是最常用的定制特征。
當更改圖例的標題時,必須綜合考慮顏色、填充、尺寸等等。可以通過fill="mytitle"
加到labs()
函數中來改變標題。
標題的位置由theme()
函數中的legen.position
選項控制。可能的值包括left, top, right(默認), bottom
。我們也可以在圖中給定的位置指定一個二元素向量。
使用添加修改上一個圖的代碼對圖形展示效果進行修改:
labs(title="Faculty Salary by Rank and Sex", x='', y='',fill='Gender')
theme(legend.position=c(.1,.8)) # 圖例的左上角分別距離左側邊緣10%,底部邊緣80%
標尺
ggplot2包使用標尺把數據空間的觀察值映射到可視化的空間中。標尺可以連續也可以離散。
在ggplot2中標尺的概念很普遍,可以通過查看以scale_開頭的函數來了解更多信息。
主題
主題可以讓我們控制這些圖的整體外觀。theme()
函數中的選項可以讓我們調整字體、背景、顏色和網格線等。主題可以使用一次,也可以保存起來應用到多個圖中。嘗試探索以下代碼:
data(Salaries, package = 'car')
library(ggplot2)
mytheme <- theme(plot.title=element_text(face="bold.italic",
size = "14", color = "brown"),
axis.title=element_text(face="bold.italic", size=10,
color="brown"),
axis.text=element_text(face="bold", size=9,
color="darkblue"),
panel.background = element_rect(fill="white",
color="darkblue"),
panel.grid.major.y=element_line(color="grey",
linetype = 2),
panel.grid.minor.y=element_line(color="grey",
linetype=2),
panel.grid.minor.x=element_blank(),
legend.position = "top")
ggplot(Salaries, aes(x=rank,y=salary,fill=sex)) +
geom_boxplot() +
labs(title="Salary by Rank and Sex", x="Rank", y="Salary") +
mytheme
多重圖
? 基礎繪圖中,我們使用圖形參數mfrow
和基本函數layout()
把兩個或多個基本圖放到單個圖中,同樣,這種方法在ggplot2中不適用。將多個ggplot2
包的圖形放到單個圖形中最簡單的方式是使用gridExtra
包中的grid.arrange()
函數。我們需要事先安裝這個包。
讓我們創建3個ggplot2圖并把它放在單個圖形中。
data(Salaries, package = 'car')
library(ggplot2)
p1 <- ggplot(data=Salaries, aes(x=rank)) + geom_bar()
p2 <- ggplot(data=Salaries, aes(x=sex)) + geom_bar()
p3 <- ggplot(data=Salaries, aes(x=yrs.since.phd, y=salary)) + geom_point()
library(gridExtra)
grid.arrange(p1,p2,p3,ncol=3)
注意截面圖(刻面圖)和多重圖的區別。
保存圖形
可以使用標準方法來保存創建的圖形,也可以使用ggsave()
函數更方便保存它們。它的選項包括保存哪幅圖形,保存在哪里和以什么形式保存。例如
myplot <- ggplot(data=mtcars, aes(x=mpg)) + geom_histogram()
ggsave(file="mygraph.png",plot=myplot,width=5,height=4)
將myplot
保存為5英寸X4英寸PNG格式。我們可以通過設置文件拓展名為ps, tex, jpeg, pdf, tiff, png, bmp, svg, wmf
來保存為不同格式。
如果忽略plot=選項
,最近創建的圖形會被保存。更多細節參考help(ggsave)
。
參考:R實戰