以三個(gè)數(shù)據(jù)集解釋ggplot2的使用。第一個(gè)是lattice包中的singer數(shù)據(jù)集,它包括紐約合唱團(tuán)歌手的高度和語音變量。第二個(gè)是mtcars數(shù)據(jù)集,它包含32輛汽車的詳細(xì)信息。最后一個(gè)是car包中的Salaries數(shù)據(jù)集,它包含大學(xué)教授的收入信息,并用來探索性別差異對(duì)它們收入的影響。這些數(shù)據(jù)集提供了各種可視化的挑戰(zhàn)。
ggplot2包介紹
在ggplot2中,圖是采用串聯(lián)起來(+)號(hào)函數(shù)創(chuàng)建的。每個(gè)函數(shù)修改屬于自己的部分。也就是說,每個(gè)函數(shù)完成圖中各個(gè)組件的相應(yīng)功能,然后通過串聯(lián)+號(hào)將其連接起來,形成一個(gè)完整的圖形。
> library(ggplot2)
> ggplot(data=mtcars, aes(x=wt, y=mpg)) +
+ geom_point() +
+ labs(title="Automobie Data", x="Weight", y="Miles Per Gallon")

分解上述圖形的制作步驟:
? ggplot()初始化圖形并指定要用到的數(shù)據(jù)來源和變量。aes()函數(shù)的功能是指定每個(gè)變量扮演的角色(aes代表aesthetics,即如何用視覺形式呈現(xiàn)信息)。在這里,變量wt的值映射到x軸,mpg的值映射到y(tǒng)軸。
? ggplot函數(shù)設(shè)置圖形但沒有自己的視覺輸出。使用一個(gè)或多個(gè)幾何函數(shù)向圖中添加了幾何對(duì)象(簡(jiǎn)寫為geom),包括點(diǎn)、線、條、箱線圖和陰影區(qū)域。在上述例子中,geom_point()函數(shù)在圖形中畫點(diǎn),創(chuàng)建了一個(gè)散點(diǎn)圖。labs()函數(shù)是可選的,可以添加注釋、軸標(biāo)簽、標(biāo)題等。
ggplot2中有很多函數(shù),并且大多數(shù)包含可選的參數(shù)。下面我們來看一下相應(yīng)擴(kuò)展。
> 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 . . .]

我們依據(jù)對(duì)最初圖形的解釋,可以很清晰的觀察到不同的函數(shù)執(zhí)行了什么樣的功能。
ggplot2包提供了分組和小面化的方法。分組指的是在一個(gè)圖形中顯示兩組或多組觀察結(jié)果。小面化指的是在單獨(dú)、并排的圖形上顯示觀察組。需要注意,ggplot2包在定義組或面時(shí)使用因子。
這里我們使用mtcars數(shù)據(jù)集查看分組和面,并進(jìn)行繪圖。

# 將變量轉(zhuǎn)換為因子
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是分組變量。
用幾何函數(shù)指定圖的類型
ggplot()函數(shù)指定要繪制的數(shù)據(jù)源和變量,幾何函數(shù)則指定這些變量如何在視覺上進(jìn)行表示。目前,有37個(gè)幾何函數(shù)可供使用。以下列出常用的函數(shù)。
| 函數(shù) | 添加 | 選項(xiàng) |
|---|---|---|
| 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() | 抖動(dòng)點(diǎn) | color, size, alpha, shape |
| geom_line() | 線圖 | colorvalpha, linetype, size |
| geom_point() | 散點(diǎn)圖 | color, alpha, shape, size |
| geom_rug() | 地毯圖 | color, sides |
| geom_smooth() | 擬合曲線 | method, formula, color, fill, linetype, size |
| geom_text() | 文字注解 | 這個(gè)非常多,參考相應(yīng)文檔 |
| geom_violin() | 小提琴圖 | color, fill, alpha, linetype |
| geom_vline() | 垂線 | color, alpha, linetype, size |
關(guān)于幾何函數(shù)的常見選項(xiàng)
| 選項(xiàng) | 詳述 |
|---|---|
| color | 對(duì)點(diǎn)、線和填充區(qū)域的邊界進(jìn)行著色 |
| fill | 對(duì)填充區(qū)域著色,如條形和密度區(qū)域 |
| alpha | 顏色的透明度,從0(完全透明)到1(不透明) |
| linetype | 圖案的線條(1=實(shí)線,2=虛線,3=點(diǎn),4=點(diǎn)破折號(hào),5=長(zhǎng)破折號(hào),6=雙破折號(hào)) |
| size | 點(diǎn)的尺寸和線的寬度 |
| shape | 點(diǎn)的形狀(和pch一樣,0=開放的方形,1=開放的圓形,2=開放的三角形,等等) |
| position | 繪制諸如條形圖和點(diǎn)等對(duì)象的位置。對(duì)條形圖來說,'dodge'將分組條形圖并排,'stacked'堆疊分組條形圖,'fill'垂直地堆疊分組條形圖并規(guī)范其高度相等。對(duì)于點(diǎn)來說,'jitter'減少點(diǎn)重疊。 |
| binwidth | 直方圖的寬度 |
| notch | 表示方塊圖是否應(yīng)為缺口(TRUE/FALSE) |
| sides | 地毯圖的安置("b"=底部, "l"=左部,"t"=頂部,"r"=右部,"bl"=左下部,等等) |
| width | 箱線圖的寬度 |
下面舉個(gè)例子來驗(yàn)證一下以上參數(shù)的使用:
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')

該圖顯示了不同學(xué)術(shù)地位對(duì)應(yīng)薪水的缺口箱線圖。實(shí)際的觀察值(教師)是重疊的,因而給予一定的透明度以避免遮擋箱線圖。它們還抖動(dòng)以減少重疊。最后,一個(gè)地毯圖設(shè)置在左側(cè)以指示薪水的一般擴(kuò)散。
當(dāng)幾何函數(shù)組合形成新類型的圖時(shí),ggplot2包的真正力量就會(huì)得到展示,讓我們利用singer數(shù)據(jù)集再來一探究竟。
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數(shù)據(jù)框中每個(gè)音部的25%,50%,75%分位數(shù)得分和任意的異常值。對(duì)于每個(gè)聲部身高范圍上的得分分布,小提琴圖展示了更多視覺線索。
接下來我們將使用幾何函數(shù)創(chuàng)建廣泛的圖表類型。讓我們從分組開始吧——在一個(gè)圖中展示多個(gè)分組觀察值。
分組
在R中,組通常用分類變量的水平(因子)來定義。
分組是通過ggplot2圖將一個(gè)或多個(gè)帶有諸如顏色、形狀、填充、尺寸和線條類型的視覺特征的分組變量來完成的。ggplot()聲明中的aes()函數(shù)負(fù)責(zé)分配變量(圖形的視覺特征)。
我們依舊以Salaries數(shù)據(jù)集來進(jìn)行相關(guān)探索。
首先,查看薪水是如何隨學(xué)術(shù)等級(jí)變化的:
data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=salary, fill=rank)) +
geom_density(alpha=.3)

接下來,我們通過性別和學(xué)術(shù)等級(jí)分組,繪制獲得博士學(xué)位年數(shù)和薪水的關(guān)系:
ggplot(Salaries, aes(x=yrs.since.phd, y=salary, color=rank, shape=sex)) +
geom_point()

最后,我們可以用一個(gè)分組的條形圖按學(xué)術(shù)等級(jí)和性別來可視化教授的人數(shù)(三種條形圖方式):



值得注意的是,第三個(gè)圖形中y軸的標(biāo)簽是錯(cuò)誤的,它應(yīng)該是比例而不是數(shù)量。我們可以通過添加y="proportion"參數(shù)到labs()函數(shù)來解決。
選項(xiàng)可以通過不同的方式使用,這取決于它們發(fā)生在aes()函數(shù)的內(nèi)部還是外部。通常來說,變量應(yīng)該設(shè)在aes()函數(shù)內(nèi),分配常數(shù)應(yīng)該在aes()函數(shù)外。
刻面
如果組在圖中并排出現(xiàn)而不是重疊為單一的圖形,關(guān)系就是清晰的。我們可以使用facet_wrap()函數(shù)和facet_grid()函數(shù)創(chuàng)建網(wǎng)格圖形(在ggplot2中也稱為刻面圖)。下表給出了相關(guān)的語法,var,rowvar,colvar是因子。
| 語法 | 結(jié)果 |
|---|---|
| facet_wrap(~var, ncol=n) | 將每個(gè)var水平排列成n列的獨(dú)立圖 |
| facet_wrap(~var, nrow=n) | 排成n行獨(dú)立圖 |
| facet_grid(rowvar~colvar) | rowvar和colvar組合的獨(dú)立圖 |
| facet_grid(rowvar~.) | 每個(gè)rowvar水平的獨(dú)立圖,配置成一個(gè)單列 |
| facet_grid(.~colvar) | 每個(gè)colvar水平的獨(dú)立圖,配置成單行 |
3個(gè)例子
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)
添加光滑曲線
這一部分我們著重分析一下添加平滑曲線到散點(diǎn)圖的方法。
我們可以使用geom_smooth()函數(shù)來添加一系列的平滑曲線和置信區(qū)域。函數(shù)的參數(shù)參考下表:
| 選項(xiàng) | 描述 |
|---|---|
| method= | 使用的平滑函數(shù)。允許的值包括lm, glm, smooth, rlm, glm,分別對(duì)應(yīng)線性、廣義線性、loess、健壯線和廣義相加模型。smooth是默認(rèn)值 |
| formula= | 在光滑函數(shù)中使用的公式。例子包括y~x, y~log(x), y~poly(x,n), y~ns(x) |
| se | 繪制置信區(qū)間(TRUE/FALSE)默認(rèn)為TRUE |
| level | 使用的置信區(qū)間水平(默認(rèn)為95%) |
| fullrange | 指定擬合應(yīng)涵蓋全圖(TRUE),或僅僅是數(shù)據(jù)(FALSE)。默認(rèn)為FALSE |
使用Salaries數(shù)據(jù)集,忽略性別和學(xué)術(shù)等級(jí),我們先檢驗(yàn)博士畢業(yè)年數(shù)和薪水之間的關(guān)系。
data(Salaries, package='car')
library(ggplot2)
ggplot(data=Salaries, aes(x=yrs.since.phd, y=salary)) +
geom_smooth() + geom_point()

統(tǒng)計(jì)函數(shù):
? ggplot2包中含有大量統(tǒng)計(jì)函數(shù)來計(jì)算所需的量,從而生產(chǎn)更多的可視化數(shù)據(jù)。通常情況下,幾何函數(shù)隱式地調(diào)用統(tǒng)計(jì)函數(shù),我們不需要直接處理這些問題。不過指導(dǎo)它們的存在是有用的。
修改ggplot2圖形的外觀
R的基礎(chǔ)繪圖中,使用par()函數(shù)或特定的畫圖函數(shù)的圖形參數(shù)來自定義基本函數(shù)。遺憾的是,這些對(duì)ggplot2圖形沒有影響,該包提供了特定了函數(shù)來改變其圖形的外觀。
坐標(biāo)軸
ggplot2包會(huì)自動(dòng)生成基本所需要的圖形參數(shù)。當(dāng)我們需要更大程度定制時(shí),需要了解相應(yīng)函數(shù)的用法。我們已經(jīng)知道labs()函數(shù)可以用來添加標(biāo)題并改變坐標(biāo)軸標(biāo)簽,讓我們?cè)倏纯雌渌挠杏煤瘮?shù):
| 函數(shù) | 選項(xiàng) |
|---|---|
| scale_x_continuous()和scale_y_continuous() | breaks=指定刻度標(biāo)記、labels=指定刻度標(biāo)記標(biāo)簽、limits=控制要展示的值的范圍 |
| scale_x_discrete()和scale_y_discrete() | breaks=對(duì)因子的水平進(jìn)行放置和排序,labels=指定這些水平的標(biāo)簽,limits=表示哪些水平應(yīng)該展示 |
| coord_filp() | 顛倒x軸和y軸 |
我們將這些函數(shù)應(yīng)用一個(gè)分組箱線圖中,其中包含按學(xué)術(shù)等級(jí)和性別分組的薪資水平,代碼如下:
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='')

圖例
圖例是指如何用顏色、形狀、尺寸等視覺特征表示數(shù)據(jù)特征的指南。標(biāo)題和位置是最常用的定制特征。
當(dāng)更改圖例的標(biāo)題時(shí),必須綜合考慮顏色、填充、尺寸等等??梢酝ㄟ^fill="mytitle"加到labs()函數(shù)中來改變標(biāo)題。
標(biāo)題的位置由theme()函數(shù)中的legen.position選項(xiàng)控制??赡艿闹蛋?code>left, top, right(默認(rèn)), bottom。我們也可以在圖中給定的位置指定一個(gè)二元素向量。
使用添加修改上一個(gè)圖的代碼對(duì)圖形展示效果進(jìn)行修改:
labs(title="Faculty Salary by Rank and Sex", x='', y='',fill='Gender')
theme(legend.position=c(.1,.8)) # 圖例的左上角分別距離左側(cè)邊緣10%,底部邊緣80%
標(biāo)尺
ggplot2包使用標(biāo)尺把數(shù)據(jù)空間的觀察值映射到可視化的空間中。標(biāo)尺可以連續(xù)也可以離散。
在ggplot2中標(biāo)尺的概念很普遍,可以通過查看以scale_開頭的函數(shù)來了解更多信息。
主題
主題可以讓我們控制這些圖的整體外觀。theme()函數(shù)中的選項(xiàng)可以讓我們調(diào)整字體、背景、顏色和網(wǎng)格線等。主題可以使用一次,也可以保存起來應(yīng)用到多個(gè)圖中。嘗試探索以下代碼:
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

多重圖
? 基礎(chǔ)繪圖中,我們使用圖形參數(shù)mfrow和基本函數(shù)layout()把兩個(gè)或多個(gè)基本圖放到單個(gè)圖中,同樣,這種方法在ggplot2中不適用。將多個(gè)ggplot2包的圖形放到單個(gè)圖形中最簡(jiǎn)單的方式是使用gridExtra包中的grid.arrange()函數(shù)。我們需要事先安裝這個(gè)包。
讓我們創(chuàng)建3個(gè)ggplot2圖并把它放在單個(gè)圖形中。
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)

注意截面圖(刻面圖)和多重圖的區(qū)別。
保存圖形
可以使用標(biāo)準(zhǔn)方法來保存創(chuàng)建的圖形,也可以使用ggsave()函數(shù)更方便保存它們。它的選項(xiàng)包括保存哪幅圖形,保存在哪里和以什么形式保存。例如
myplot <- ggplot(data=mtcars, aes(x=mpg)) + geom_histogram()
ggsave(file="mygraph.png",plot=myplot,width=5,height=4)
將myplot保存為5英寸X4英寸PNG格式。我們可以通過設(shè)置文件拓展名為ps, tex, jpeg, pdf, tiff, png, bmp, svg, wmf來保存為不同格式。
如果忽略plot=選項(xiàng),最近創(chuàng)建的圖形會(huì)被保存。更多細(xì)節(jié)參考help(ggsave)。
參考:R實(shí)戰(zhàn)
