第4章 用圖層構建圖像
每個圖層孝可以有自己的數據集和圖形屬性映射络断,附加的數據元素可以通過圖層添加到圖形中菜职。
4.2 創(chuàng)建繪圖對象
ggplot()函數,有兩個主要參數:數據和圖形屬性映射燕鸽。這兩個參數被設定為繪圖的默認參數闪彼,只有在新添加的圖層里設定新的參數時,默認值都會被修改粥喜。
- 數據data,指定繪圖所用的默認數據集(必須是數據框dataframe)额湘;
- 映射mapping旁舰,將圖形屬性和變量名放至函數aes()內。
p <- ggplot(diamonds, aes(carat, price, colour = cut))
這個圖形對象在加上圖層之前無法顯示箭窜。
4.3 圖層
因為每一個幾何對象都對應著一個默認的統(tǒng)計變換和位置參數,而每一個統(tǒng)計變換都對應著一個默認的幾何對象參數磺樱,所以對于一個圖層纳猫,我們只需要設定stat或geom參數即可。
- geom_XXX(mapping, data, ..., stat, position)
- stat_XXX(mapping, data, ..., geom, position)
它們的參數定義了圖層的各種組件:
- mapping(可選): 一組圖形屬性映射竹捉,通過aes()函數來設定芜辕;
- data(可選):一個數據集,可以修改默認數據集块差;
- ...:geom或stat的參數侵续,如直方圖的組距(binwidth)或者loess曲線的帶寬(bandwidth)。
- geom或stat(可選):可以修改geom默認的stat值憾儒,或stat默認的geom值询兴。它們是一組字符串,包含了將要使用的幾何對象或統(tǒng)計變換的名稱起趾。
- position(可選):選擇一種調整對象重合的方式诗舰。
注意,在圖形對象中一般先設定數據集训裆,而在圖層函數中一般先設定圖形屬性眶根。
4.4 數據
數據集必須是一個數據框(data frame)蜀铲。
數據是以副本而不是引用的形式存儲到圖形對象中。有兩個好處:
- 如果數據變了属百,繪圖不會改變记劝;
- ggplot2的對象都是自含型的(self-contained),可以被存儲到磁盤上族扰,并可以被直接加載運行(load())厌丑。
4.5 圖形屬性映射
aes()函數用來將數據變量映射到圖形中,從而使變量成為可以被感知的圖形屬性渔呵。
aes(x=weight, y=height, colour=age)
4.5.1 圖和圖層
默認的圖形屬性映射可以在圖形對象初始化時設定怒竿,
p <- ggplot(mtcars, aes(x=mpg, y=wt))
p + geom_point()
或者過后用+修改。
p + geom_point(aes(colour = factor(cyl))
p + geom_point(aes(y=disp))
p <- ggplot(mtcars, aes(x=mpg, y=wt))
p1 <- p + geom_point()
p2 <- p + geom_point(aes(colour = factor(cyl))) #添加
p3 <- p + geom_point(aes(y=disp)) #修改
grid.arrange(p1, p2, p3, ncol=3)
一個圖層里設定的圖形屬性映射只對該圖層起作用扩氢。因此第三張圖只改變了坐標點(aes(mpg,disp)),并沒有改變坐標軸標簽(wt)朦肘。
4.5.2 設定和映射
除了可以將一個圖形屬性映射到一個變量双饥,也可以在圖層的參數將其設定為一個單一值咏花,如colour="red"。
p <- ggplot(mtcars, aes(mpg,wt))
p1 <- p + geom_point(colour = "darkblue") #將點設定為深藍色。
p2 <- p + geom_point(aes(colour="darkblue")) #將colour映射到“darkblue”顏色
grid.arrange(p1,p2, ncol=2)
第二張圖矩父,將將colour映射到“darkblue”顏色窍株。實際上是先創(chuàng)建了一個只含有“darkblue"字符的變量球订,然后將colour映射到這個新變量瑰钮。因為這個新變量的值是離散型的浪谴,所有默認的顏色標度用色輪上等間距的顏色因苹,并且由于只有一個值扶檐,所以這個顏色就是默認的桃紅色款筑。
4.5.3 分組
在ggplot2中奈梳,幾何對象可以大致分為個體幾何對象和群組幾何對象兩大類:
- 個體(individual)幾何對象哮翘,對數據框的每一條數據繪制一個可以區(qū)別于其他個體的圖形對象饭寺。如,點幾何對象用點來表示每一條觀測限煞。
- 群組(collective)幾何對象署驻,用來表示多條觀測旺上,它們可以是某個統(tǒng)計摘要的一個結果宣吱,或者是幾何對象的基礎展示瞳别,如多邊形祟敛。
- 線條和路徑介于兩者之間:每條線都由許多線段組成馆铁,每條線段又代表兩個點。
分組(group)圖形屬性的工作就是控制哪些觀測值用哪種圖形元素畔裕。
- 圖中所有離散型變量的交互作用被設為分組的默認值。
- 如果沒能正確分組或者圖中沒有離散型變量具练,那么就需要自定義分組結構扛点,即將group映射到一個在不同的組有不同取值的變量陵究。
- 當現有的單個變量不能夠正確地分組铜邮,而兩個變量的組合可以正確分組時寨蹋,使用interactio()函數已旧。
下面的案例使用nlme包里的一個簡單的縱向數據集Oxboys。該數據記錄了26個男孩(Subject)在9個不同時期(Occasion)所測定的身高(height)和中心化后的年齡(age)惊楼。
多個分組與單個圖形屬性
library(nlme)
p1 <- ggplot(Oxboys, aes(age, height, group=Subject)) + geom_line()
p2 <- ggplot(Oxboys, aes(age, height)) + geom_line()
grid.arrange(p1,p2,ncol=2)
這里指定Subject為分組變量檀咙,每個男孩對應一條線攀芯。如果不指定,就會得到一條通過每個點的單一線條氧秘,沒有任何意義丸相。
不同圖層上的不同分組
根據不同水平下的數據整合來對統(tǒng)計匯總信息(summary)進行圖形繪制彼棍。
即,有的圖層展示個體水平的數據弛作,有的圖層展示更大組群的統(tǒng)計信息映琳。
假設我們想根據所有男孩的年齡和身高在圖中添加一條光滑線條萨西。
library(nlme)
p <- ggplot(Oxboys, aes(age, height, group=Subject)) + geom_line()
p1 <- p+geom_smooth(aes(group=1), method="lm", size=2, se=F)
p1
新圖層需要一個不同的分組圖形屬性谎脯,group=1源梭,繪出的線條是基于整體數據的。如果是group=Subject矢否,則給每個男孩添加一條光滑線條僵朗。
修改默認分組
如果圖像中含有離散型變量验庙,而你卻想繪制連貫所有分組的線條粪薛,那么你可以采取繪制交互作用圖搏恤、輪廓圖以及平行坐標圖時所用的策略熟空。
以繪制各個測量時期(Occasion)身高(height)的箱線圖為例息罗,
#Occasion是一個離散型變量,所以默認分組變量是Occasion温圆。
boysbox <- ggplot(Oxboys, aes(Occasion, height)) + geom_boxplot()
#添加個人軌跡孩革,用aes(group=Subject)修改第一層的默認分組嫉戚。
boysbox2 <- boysbox + geom_line(aes(group = Subject), colour="darkblue")
grid.arrange(boysbox, boysbox2, ncol=2)
4.5.4 匹配圖形屬性和圖形對象
(省略)
4.6 幾何對象
- 幾何對象簡稱geom彬檀,執(zhí)行圖層的實際渲染窍帝,控制生成的圖像類型坤学。如用點幾何屬性(point geom)將會生成散點圖。
- 每個幾何對象都有一組它能識別的圖形屬性和一組繪圖所需的值压怠。例如菌瘫,一個點含有顏色雨让、大小栖忠、和形狀等圖形屬性贸街,以及x和y位置坐標薛匪。
- 每個幾何對象都有一個默認的統(tǒng)計變換,并且每一個統(tǒng)計變換都有一個默認的幾何對象。如封箱(bin)統(tǒng)計變換默認使用條狀幾何對象(bar geom)來繪制直方圖冷溶。
名稱 | 描述 | 默認統(tǒng)計變換 | 圖形屬性 |
---|---|---|---|
abline | 線逞频,由斜率和截距決定 | abline | colour, linetype, size |
area | 面積圖(area plot) | identity | colour, fill, linetype, size, x, y |
bar | 條形圖 | bin | colour, fill, linetype, size, weight, x |
bin2d | 2維熱圖 | bin2d | colour, fill, linetype, size, weight, xmax, xmin, ymax, ymin |
blank | 空白苗胀,什么也不畫 | identity | |
boxplot | 箱線圖 | boxplot | colour, fill, lower, middle, size, weight, x, ymax, ymin |
contour | 等高線圖 | contour | colour, fill, linetype, size, weight, x, y |
crossbar | 帶水平中心線的盒子圖 | identity | colour, linetype, size, weight, x, y, ymax, ymin |
density | 光滑密度曲線圖 | density | colour, fill, linetype, size, weight, x, y |
density2d | 2維密度等高線圖 | density2d | colour, fill, linetype, size, weight, x, y |
dotplot | 點直方圖基协,用點表示觀測值的個數 | bindot | colour, fill, x, y |
errorbar | 誤差棒 | identity | colour, linetype, size, width, x, ymax, ymin |
errorbarh | 水平誤差棒 | identity | colour, linetype, size, width, y, ymax, ymin |
freqpoly | 頻率多邊形圖 | bin | colour, fill, linetype, size, weight, x |
hex | 用六邊形表示的2維熱圖 | binhex | colour, fill, size, x, y |
histogram | 直方圖 | bin | colour, fill, linetype, size, weight, x |
hline | 水平線 | hline | colour, fill, linetype, size |
jitter | 給點添加擾動陷揪,減輕圖形重疊問題 | identity | colour, fill, shape, size, x, y |
line | 按x坐標的大小順序依次連接各個觀測值 | identity | colour, linetype, size, x, y |
linerange | 一條代表一個區(qū)間的豎直線 | identity | colour, linetype, size, x, ymax, ymin |
map | 基準地圖里的多邊形 | identity | colour, fill, linetype, size, x, y, map_id |
path | 按數據的原始順序連接各個觀測值 | identity | colour, linetype, size, x, y |
point | 散點圖 | identity | colour, fill, shape,size, x, y |
pointrange | 用一條中間帶點的豎直線代表一個區(qū)間 | identity | colour, fill, linetype, shape size, x, y, ymax, ymin |
polygon | 多邊形悍缠,相當于一個有填充的路徑 | identity | colour, fill, linetype, size, x, y |
quantile | 添加分位數回歸線 | quantile | colour, linetype, size, weight, x, y |
raster | 高效的矩形瓦片圖 | identity | colour, fill, linetype, size, x, y |
rect | 2維的矩形圖 | identity | colour, fill, linetype, size, xmax, xmin, ymax, ymin |
ribbon | 色帶圖飞蚓,連續(xù)的x值所對應的y的范圍 | identity | colour, fill, linetype, size, x, ymax, ymin |
rug | 邊際地毯圖 | identity | colour, linetype, size |
segment | 添加線段或箭頭 | identity | colour, linetype, size, x, xend, y, yend |
smooth | 添加光滑的條件均值線 | smooth | alpha, colour, fill, linetype, size, weight, x, y |
step | 以階梯形式連接各個觀測值 | identity | colour, linetype, size, x, y |
text | 文本注釋 | identity | angle, colour,hjust, label, size, vjust, x, y |
tile | 瓦片圖 | identity | colour, fill, linetype, size, x, y |
violin | 小提琴圖 | ydensity | weight, colour, fill, size, linetype, x, y |
vline | 豎直線 | vline | colour, linetype, size |
4.7 統(tǒng)計變換
統(tǒng)計變換趴拧,簡稱stat八堡,即對數據進行統(tǒng)計變換兄渺,通常以某種方式對數據信息進行匯總民挂谍。
名稱 | 描述 |
---|---|
bin | 計算封箱(bin)數據 |
bin2d | 計算矩形封箱內的觀測值個數 |
bindot | 計算“點直方圖”的封箱數據 |
binhex | 計算六邊形熱圖的封箱數據 |
boxplot | 計算組成箱線圖的各元素值 |
contour | 三維數據的等高線 |
density | 一維密度估計 |
density2d | 二維密度估計 |
function | 添加新函數 |
identity | 不對數據進行統(tǒng)計變換 |
計算qq圖的相關值 | |
quantile | 計算連續(xù)的分位數 |
smooth | 添加光滑曲線 |
spoke | 將角度和半徑轉換成xend和yend |
sum | 計算每個單一值的頻數口叙,有助于解決散點圖的圖形重疊問題 |
summary | 對每個x所對應的y值做統(tǒng)計描述 |
summary2d | 對2維矩形封箱設定函數 |
summaryhex | 對2維六邊形封箱設定函數 |
unique | 刪除重復值 |
ydensity | 小提琴圖妄田,計算1維y軸方向的核密度函數估計值 |
統(tǒng)計變換可將輸入的數據集看做輸入,將返回的數據集作為輸出脚曾,因此統(tǒng)計變換可以向原數據集中插入新的變量本讥。
例如鲁冯,直方圖的stat_bin統(tǒng)計變換會生成如下變量:
- count, 每個組里觀測值的數目薯演;
- density, 每個組里觀測值的密度(占整體的百分數/組寬)涣仿;
- x, 組的中心位置。
這些生成的變量可以被直接調用愉镰。生成變量的名字必須要用..圍起來丈探。這樣可防止原數據集中的變量與生成變量重名時造成的混淆碗降。
ggplot(diamonds, aes(carat)) + geom_histogram(aes(y=..density..), binwidth = .1)
4.8 位置調整
位置調整讼渊,即對該層中的元素位置進行微調爪幻。
位置調整须误,一般多見于處理離散型數據京痢。
名稱 | 描述 |
---|---|
dodge | 避免重疊,并排放置 |
fill | 堆疊圖形元素并將高度標準化為1 |
identity | 不做任何調整 |
jitter | 給點添加擾動避免重合 |
stack | 將圖形元素堆疊起來 |
p1 <- ggplot(diamonds, aes(x=clarity)) + geom_bar(aes(fill=cut), position="stack")
p2 <- ggplot(diamonds, aes(x=clarity)) + geom_bar(aes(fill=cut), position="fill")
p3 <- ggplot(diamonds, aes(x=clarity)) + geom_bar(aes(fill=cut), position="dodge")
grid.arrange(p1,p2,p3, ncol=2)
4.9 整合
4.9.1 結合幾何對象和統(tǒng)計變換
d <- ggplot(diamonds, aes(carat)) + xlim(0,3)
d1 <- d+stat_bin(aes(ymax=..count..), binwidth = 0.1, geom="area")
d2 <- d+stat_bin(aes(size=..density..), binwidth = 0.1, geom="point", position="identity")
# d3 <- d+stat_bin(aes(y=1, fill=..count..), binwidth = 0.1, geom="tile", position="identity")
grid.arrange(d1, d2, ncol=2)
d+stat_bin(aes(y=..count.., linetype=cut), binwidth = 0.1, geom="line", position="identity")
4.9.2 顯示已計算過的統(tǒng)計量
如果你有已經匯總過的數據,并想直接用它钉赁,而不進行其他統(tǒng)計變換橄霉,可以使用stat_identity()姓蜂,然后將合適的變量映射到相應的圖形屬性中医吊。
4.9.3 改變圖形屬性和數據集
如何結合統(tǒng)計模型輸出的結果和原始數據來更深刻地理解數據和模型卿堂。
require(nlme, quiet=TRUE, warn.conflicts = FALSE)
#擬合一個截距和斜率都包含隨機效應的混合模型
model <- lme(height ~ age, data=Oxboys, random = ~ 1+age|Subject)
oplot <- ggplot(Oxboys, aes(age, height, group=Subject))+geom_line()
#建立一個包含所有年齡(age)和個體(subjects)組合的網絡數據框。
age_grid <- seq(-1, 1, length=10)
subjects <- unique(Oxboys$Subject)
preds <- expand.grid(age=age_grid, Subject=subjects)
#把模型的預測值添加到新變量height
preds$height <- predict(model, preds)
#把預測值和原始數據繪制到同一張圖上
oplot+geom_line(data=preds, colour="red", size=0.4)
#比較模型擬合好壞的另一種方法是觀察殘差览绿。
#把擬合值(fitted)和殘差(resid)都添加到原數據里饿敲。
Oxboys$fitted <- predict(model)
Oxboys$resid <- with(Oxboys, fitted-height)
#更新數據集(用%+%)逛绵,將默認的y圖形屬性改為resid术浪,最后對整個數據添加一條光滑曲線。
oplot %+% Oxboys +aes(y=resid) +geom_smooth(aes(group=1))
#向模型添加二次項硕蛹,再次計算擬合值和殘差并重新繪制殘差圖碟联。
model2 <- update(model, height ~ age + I(age^2))
Oxboys$fitted2 <- predict(model2)
Oxboys$resid2 <- with(Oxboys, fitted2-height)
oplot %+% Oxboys + aes(y=resid2) + geom_smooth(aes(group=1))