6.1 簡介
標度控制着數據到圖形屬性的映射。標度將我們的數據轉化為視覺上可以感知的東西:例如大小、顏色、位置和形狀。標度也為我們提供了讀圖時所使用的工具:坐標軸和圖例。
執行標度的過程分為三步:變換、訓練和映射。
標度可以粗略地分為四類:位置標度、顏色標度、手動離散型標度以及同一型標度。
6.2 標度的工作原理
標度的定義域即數據空間,值域即圖形屬性空間。當輸入變量是離散型時,標度的定義域是某些值組成的集合,它的值域是輸入值對應的圖形屬性值組成的一個向量;當輸入變量是連續型時,標度的定義域是一個實值區間,它的值域是穿過某種更復雜的空間的一條一維路徑,例如,從一種顏色到另一種顏色進行線性插值得到的一組漸變顏色。
- 變換:對連續型數據進行適當的變換往往是有益的,例如取對數或者開根號。
- 訓練:通過學習得到標度的定義域,在一個僅有一個圖層且僅呈現原始數據的圖形中,這個學習過程包括確定某個連續型變量的最大值和最小值,或者是列出某個類別型變量的所有水平。
- 映射:執行映射數據到圖形的函數。
6.3 用法
每一種圖形屬性都擁有一個默認的標度,此標度將在我們每次使用這個圖形屬性時被自動地添加到圖形中。
圖形屬性 | 離散型 | 連續型 |
顏色(colour)和填充色(fill) | brewer | gradient |
gery | gradient2 | |
hue | gradientn | |
identity | ||
manual | ||
位置(position)(x, y) | discrete | continuous |
date | ||
形狀(shape) | shape | |
identity | ||
manual | ||
線條類型(line type) | linetype | |
identify | ||
manual | ||
大小(size) | identity | size |
manual |
如果要添加一個不同的標度或者修改默認標度的某些特征,我們必須構造一個新的標度,然后使用+將其添加到圖形上。所有的標度構建器都有一套通用的命名方案。它們以scale_開頭,接下來是圖形屬性的名稱(例如,colour_、shape_或x_),最后以標度的名稱結尾(例如,gradient、hue或manual)。舉例來說,離散型數據的顏色圖形屬性的默認標度名為scale_colour_hue(),填充色的Brewer配色標度名為scale_fill_brewer()。
p <- qplot(sleep_total, sleep_cycle, data = msleep, colour = vore) p # 顯式添加默認標度 p + scale_colour_hue() # 修改默認標度的參數, 這里改變了圖例的外觀 p + scale_colour_hue("What does\nit eat?", breaks = c("herbi", "carni", "omni", NA), labels = c("plants", "meat", "both", "don’t know")) # 使用一種不同的標度 p + scale_colour_brewer(palette = "Set1")
調整標度默認參數的示例:(左上圖)使用默認標度的圖形。(右上圖)手動添加默認標度,並未改變圖形外觀。(左下圖)調整標度的參數以實現對圖例的調整。(右下圖)使用一種不同的顏色標度:ColorBrewer配色方案中的Set1。
6.4 標度詳解
- 位置標度:用於將連續型、離散型和日期-時間型變量映射到繪圖區域,以及構造對應的坐標軸;
- 顏色標度:用於將連續型和離散型變量映射到顏色;
- 手動離散型標度:用於將離散型變量映射到我們選擇的符號大小、線條類型、形狀或顏色,以及創建對應的圖例;
- 同一型標度:用於直接將變量值繪制為圖形屬性,而不去映射它們。比如假設我們想要將變量映射為符號的顏色,而此變量本身就是一個由顏色值組成的向量,那么我們就無需再將其映射為其他的顏色,直接渲染這些值本身即可。
6.4.1 通用參數
以下參數對所有標度通用。
- name:設置坐標軸或圖例上出現的標簽。可以指定字符串(使用\n換行)或數學表達式(語法在??plotmath中)。由於經常需要微調這些標簽,所以使用三個輔助函數xlab()、ylab()、labs()可以使我們減少部分輸入。
p <- qplot(cty, hwy, data = mpg, colour = displ) p p + scale_x_continuous("City mpg") p + xlab("City mpg") p + ylab("Highway mpg") p + labs(x = "City mpg", y = "Highway", colour = "Displacement") p + xlab(expression(frac(miles, gallon)))
- limits:固定標度的定義域。連續型標度接受一個長度為2的數值型向量;離散型標度接受一個字符型向量。一旦設定了limits,數據將不再進行任何訓練。限制定義域可以幫助我們移除不想在圖形上展示的數據,或者保證要進行比較的多個圖形中的繪制范圍一致。
任何不在此標度定義域內的值均將被丟棄,丟棄過程發生在統計量的計算之前。
- breaks和labels:breaks控制着顯示在坐標軸或圖例上的值,即坐標軸上應該顯示哪些刻度線的值,或者一個連續型標度在一個圖例中將如何分段。labels指定了應在斷點處顯示的標簽。若設置了labels,則必須同時指定breaks,只有這樣,這兩個參數才能被正確匹配。
- formatter:如果未指定任何標簽,則將在每個斷點處自動調用格式刷來生成標簽。對於連續型標度,可用的標簽刷為:comma、percent、dollar和scientific;對於離散型標度,則為abbreviate。
6.4.2 位置標度
- xlim(10, 20):一個從10到20的連續型標度;
- ylim(20, 10):一個從20到10的反轉后連續型標度。
- xlim("a", "b", "c"):一個離散型標度;
- xlim(as.Data(c("2008-05-01", "2008-08-01"))):一個日期型標度。
在ggplot2中,為了保持與其他標度的一致性,任何在limits以外的數據都不會被繪制,也不會被包括在統計變換的過程中。這意味着,通過設置limits所得的結果與在視覺上放大一塊繪圖區域所得的結果是不同的。要實現后者,需要使用coord_cartesian()函數的參數xlim和ylim,這種方式單純地對圖形進行了視覺上的放大,而不影響底層函數的數據。
默認情況下,位置標度的limits會稍微超出數據的范圍,這樣就保證了數據與坐標軸不會發生重疊,我們可以使用參數expand來控制溢出量,此參數是長度為2的數值型向量,第一個參數給出的是乘式的溢出量,第二個參數給出的是加式的溢出量。使用expand = c(0, 0)來去掉任何多余的空間。
連續型
每個連續型標度均可接受一個trans參數,允許指定若干種線性或非線性變換。
scale_x_log10()與scale_x_continuous(trans = "log10")等價。
qplot(log10(carat), log10(price), data = diamonds) qplot(carat, price, data = diamonds) + scale_x_log10() + scale_y_log10()
直接繪制log10(x)和scale_x_log10()在繪圖區域生成完全相同的結果,但坐標軸和刻度標簽卻是不同的。
日期和時間
對於日期坐標軸,有三個參數可以用於控制其外觀和刻度的位置:major、minor和format。
- 參數major和minor用以按照時間的單位,及年(year)、月(month)、周(week)、日(day)、時(hour)、分(minute)、秒(second)來指定主要和次要斷點的位置。並且允許以這些單位的倍數出現,例如,major = "2 weeks" 在每隔兩周的位置放置一個主刻度。
- 參數format指定了刻度標簽的格式。如下表所示。
編碼 | 含義 |
%S | 秒(00-59) |
%M | 分鍾(00-59) |
%l | 小時,12小時制(1-12) |
%I | 小時,12小時制(01-12) |
%H | 小時,24小時制(00-23) |
%a | 縮寫的周幾(Mon-Sun) |
%A | 全稱的周幾(Monday-Sunday) |
%e | 某月中的某天(1-31) |
%d | 某月中的某天(01-31) |
%m | 以數值表示的月份(01-12) |
%b | 縮寫的月份(Jan-Dec) |
%B | 全稱的月份(January-December) |
%y | 不含世紀的年份(00-99) |
%Y | 含世紀的年份(0000-9999) |
library(scales) p <- qplot(date, psavert, data = economics, geom = "line") + ylab("Personal savings rate") p p + scale_x_date(limits = as.Date(c("2004-01-01", "2005-01-01")), labels = date_format("%Y-%m-%d"))
6.4.3 顏色標度
連續型
- scale_colour_gradient()和scale_fill_gradient():雙色梯度,順序為從低到高,low和high用以控制此梯度兩端的顏色。
- scale_colour_gradient2()和scale_fill_gradient2():三色梯度,low、high和midpoint。
- scale_colour_gradientn()和scale_fill_gradientn():自定義的n色標度。
此標度需要賦給參數colours一個顏色向量。不加其他參數的話,這些顏色將依照數據的范圍均勻地分布。如果需要讓這些值不均勻地分布,則可以使用參數values。如果rescale取值為TRUE(默認),則values應在0~1之間取值,如果rescale的取值為FALSE,則values應在數據范圍內取值。
f2d <- with(faithful, MASS::kde2d(eruptions, waiting, h = c(1, 10), n = 50)) str(f2d) df <- with(f2d, cbind(expand.grid(x, y), as.vector(z))) names(df) <- c("eruptions", "waiting", "density") str(df) erupt <- ggplot(df, aes(waiting, eruptions, fill = density)) + geom_tile() + scale_x_continuous(expand = c(0, 0)) + scale_y_continuous(expand = c(0, 0)) erupt + scale_fill_gradient(limits = c(0, 0.04), low = "white", high = "black") erupt + scale_fill_gradient2(limits = c(-0.04, 0.04), midpoint = mean(df$density)) erupt + scale_fill_gradientn(colours = topo.colors(10)) erupt + scale_fill_gradientn(colours = terrain.colors(10)) erupt + scale_fill_gradientn(colours = heat.colors(10)) #自定義 erupt + scale_fill_gradientn(values = c(0,0.2,0.4,0.6,0.8,1), colors = c("red", "yellow", "green", "blue", "purple"))
kde2d {MASS}:Two-Dimensional Kernel Density Estimation;
expand.grid {base}:Create a Data Frame from All Combinations of Factor Variables。
離散型
離散型數據有兩種顏色標度,一種可以自動選擇顏色,另一種從手工甄選的顏色集中選擇顏色。
RColorBrewer::display.brewer.all()
默認的配色方案即scale_colour_hue()可以通過沿着hcl色輪選取均勻分布的色相來生成顏色。缺點是:顏色多於8種時區分困難;所有的顏色都擁有相同的明度和彩度,所以在進行黑白打印時幾乎成為相同的灰影。
使用ColorBrewer配色:對點一般使用"set1"和"Dark2",對面積則是"Set2"、"paster1"、"Pastel2"和"Accent"。這是因為更明亮的顏色對點效果良好,但對於條形來說過於刺眼。淡色對條形效果良好,但會讓點看不清楚。
point <- qplot(brainwt, bodywt, data = msleep, log = "xy", colour = vore) area <- qplot(log10(brainwt), data = msleep, fill = vore, binwidth = 1) point + scale_colour_brewer(palette = "Set1") point + scale_colour_brewer(palette = "Set2") point + scale_colour_brewer(palette = "Pastel1") area + scale_fill_brewer(palette = "Set1") area + scale_fill_brewer(palette = "Set2") area + scale_fill_brewer(palette = "Pastel1")
6.4.4 手動離散型標度
離散型標度scale_linetype()、scale_size_discrete()和scale_shape()基本上沒有選項,這些標度僅僅是按照一定的順序將因子的水平映射到一系列的取值中。如果需要定值這些標度,可以使用scale_linetype_manual()、scale_colour_manual()和scale_shape_manual()。如果values向量中的元素師有名稱的,則它將自動匹配輸入和輸出可用的圖形屬性值,否則將按照離散型變量中水平的先后次序進行匹配。
plot <- qplot(brainwt, bodywt, data = msleep, log = "xy") plot + aes(colour = vore) + scale_colour_manual(values = c("red", "orange", "yellow", "green", "blue")) colours <- c(carni = "red", `NA` = "orange", insecti = "yellow", herbi = "green", omni = "blue") plot + aes(colour = vore) + scale_colour_manual(values = colours) plot + aes(shape = vore) + scale_shape_manual(values = c(1, 2, 6, 0, 23))
使用colours()得到R中支持的詳細的顏色列表。
> head(colours(),10) [1] "white" "aliceblue" "antiquewhite" "antiquewhite1" [5] "antiquewhite2" "antiquewhite3" "antiquewhite4" "aquamarine" [9] "aquamarine1" "aquamarine2"
多變量繪圖!!
ggplot(huron, aes(year)) + geom_line(aes(y = level - 5, colour = "below")) + geom_line(aes(y = level + 5, colour = "above")) + scale_colour_manual("Direction", values = c(below = "blue", above = "red"))