ggplot2作圖詳解7(完):主題(theme)設置
凡是和數據無關的圖形設置內容理論上都可以歸為主題類,但考慮到一些內容(如坐標軸)的特殊性,可以允許例外的情況。主題的設置相當繁瑣,很容易就占用了 大量的作圖時間,應盡量把這些東西簡化,把註意力主要放在數據分析上。基於這種考慮,ggplot2主題設置的內容雖然相當多,本文僅在總體上作一簡單介 紹。
1 theme函數及其參數
讓使用者在數據分析階段能專註於數據而不是圖形細節,這是數據可視化分析工具是否合格的標準之一。某些作圖軟件(或自以為有作圖能力的軟件)給出的初始圖 形簡直慘不忍睹,不花時間修改字體、邊距、底紋這些東西就惡心得沒法繼續分析數據。ggplot2做得還可以:即使不做任何設置,多數情況下作出的圖形都 還不錯,不醜陋也不妖艷,不會分散用戶的註意力。這得益於ggplot2的幾個預設主題。
ggplot2的四個預設主題我們在前面已經預覽過了,下面我們看看主題都包含了哪些東西。這很容易,把ggplot2默認主題的設置函數theme_gray()的代碼拿出來看看就知道了:
library(ggplot2) theme_gray # 函數名不加括號,獲得函數的代碼
## 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) ## }
##
看穿了吧,沒神秘感了。它無非是一個具有兩個參數的函數:base_size和base_family。其主題部分直接應用了另外一個函數:theme。它就是ggplot2的主題設置函數。這個theme函數的產生看起來非常簡單:
# 函數說明,非運行代碼 theme(..., complete = FALSE)
但dotdotdot(···)參數卻內涵豐富,它可以設置很多內容。
參數 | 設置內容 | 繼承自 |
line | 所有線屬性 | |
rect | 所有矩形區域屬性 | |
text | 所有文本相關屬性 | |
title | 所有標題屬性 | |
axis.title | 坐標軸標題 | text |
axis.title.x | x軸屬性 | axis.title |
axis.title.y | y軸屬性 | axis.title |
axis.text | 坐標軸刻度標簽屬性 | text |
axis.text.x | 屬性和繼承和前面類似,不再重復 | |
axis.text.y | ||
axis.ticks | 坐標軸刻度線 | line |
axis.ticks.x | ||
axis.ticks.y | ||
axis.ticks.length | 刻度線長度 | |
axis.ticks.margin | 刻度線和刻度標簽之間的間距 | |
axis.line | 坐標軸線 | line |
axis.line.x | ||
axis.line.y | ||
legend.background | 圖例背景 | rect |
legend.margin | 圖例邊界 | |
legend.key | 圖例符號 | |
legend.key.size | 圖例符號大小 | |
legend.key.height | 圖例符號高度 | |
legend.key.width | 圖例符號寬度 | |
legend.text | 圖例文字標簽 | |
legend.text.align | 圖例文字標簽對齊方式 | 0為左齊,1為右齊 |
legend.title | 圖例標題 | text |
legend.title.align | 圖例標題對齊方式 | |
legend.position | 圖例位置 | left, right, bottom, top, 兩數字向量 |
legend.direction | 圖例排列方向 | "horizontal" or "vertical" |
legend.justification | 居中方式 | center或兩數字向量 |
legend.box | 多圖例的排列方式 | "horizontal" or "vertical" |
legend.box.just | 多圖例居中方式 | |
panel.background | 繪圖區背景 | rect |
panel.border | 繪圖區邊框 | rect |
panel.margin | 分面繪圖區之間的邊距 | |
panel.grid | 繪圖區網格線 | line |
panel.grid.major | 主網格線 | |
panel.grid.minor | 次網格線 | |
panel.grid.major.x | ||
panel.grid.major.y | ||
panel.grid.minor.x | ||
panel.grid.minor.y | ||
plot.background | 整個圖形的背景 | |
plot.title | 圖形標題 | |
plot.margin | 圖形邊距 | top, right, bottom, left |
strip.background | 分面標簽背景 | rect |
strip.text | 分面標簽文本 | text |
strip.text.x | ||
strip.text.y |
除一些尺寸設置有關的內容外(需要用grid包的unit函數設置),幾乎所有元素都在theme函數內使用 element_line,element_rect,element_text和element_blank函數設置,使用方法參考這幾個函數的參數說 明即可,這裏不再一一舉例說明。
text, line, rect和title是最頂層的元素,理論上可以做全局設定,但當前版本ggplot2還沒有實現,可以根據情況做一些調整:
x <- LETTERS[1:10] y <- abs(rnorm(10)) (p <- qplot(x = x, y = y, color = x, fill = x,geom = c("line", "point"), group = 1) + labs(title = "The figure title.", xlab ="Factor", ylab = "Value") + theme(text = element_text(color = "red", size = 16), line =element_line(color = "blue"), rect = element_rect(fill = "white"))) p +theme(panel.background = element_rect(fill = "transparent", color = "gray"), legend.key= element_rect(fill = "transparent", color = "transparent"), axis.text =element_text(color = "red"))
全局text和rect設置對部分元素有作用,line基本不起作用。
2 自定義主題
圖形細節設置雖然繁瑣,但是在R中可以相當簡單。由於自己使用的或者雜誌要求的圖形外觀一般都很固定,我們可以使用ggplot2的theme函數非常方便地定義自己的圖形主題。下面是我自用的一個主題函數,主要作的改動是坐標軸刻度朝向和統一了圖形各個區域的背景顏色:
##‘ A nice-looking ggplot2 theme: inward axis ticks, legend title excluded, and uniform background. ##‘ @title A nice-looking ggplot2 theme ##‘ @param ... ##‘ Parameters passed to theme_classic() function. ##‘ @param bg ##‘ Color string (default ‘white‘) for user defined uniform background. ##‘ @return ##‘ ggplot2 theme object. ##‘ @examples ##‘ library(ggplot2) ##‘ qplot(x=carat, y=price, color=cut, data=diamonds) + theme_zg() ##‘ @author ZGUANG ##‘ @export theme_zg <- function(..., bg=‘white‘){ require(grid)theme_classic(...) + theme(rect=element_rect(fill=bg), plot.margin=unit(rep(0.5,4),‘lines‘), panel.background=element_rect(fill=‘transparent‘, color=‘black‘),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.4,"lines"), axis.ticks = element_line(color=‘black‘),axis.ticks.margin = unit(0.8,"lines"), legend.title=element_blank(),legend.key=element_rect(fill=‘transparent‘, color=‘transparent‘)) }
自定義的主題可以編入自己的R語言包中,方便調用。如果覺得你的主題很有代表性,可以發給ggplot2的作者H.W.,讓他加到ggplot2的下一個發行版中。比如上面上面函數加入ggplot2後就可以直接調用:
p <- qplot(x = x, y = y, color = x, fill = x, geom = c("line", "point"), group = 1) +labs(title = "The figure title.", xlab = "Factor", ylab = "Value") p + theme_zg() p +theme_zg(base_size = 16, bg = "gray90")
3 結束語
本系列博文到此結束。ggplot2還在完善過程中,一些新功能可能不斷會實現,感謝H.W的努力。有一些本應屬於主題類的東西不能在theme_set 函數中設置,需要使用特殊的函數,如坐標軸翻轉、刻度設置等,在這不再介紹。如果想比較透徹的學習,建議把ggplot2項目從GitHub克隆下來研究 它的代碼。更好的方法是研究ggmap和ggbio這兩個包,它們的代碼本身就是ggplot2應用的最好範例。尤其是ggmap,H.W.是它的作者之 一。
本系列文章的例子基於ggplot2 0.9.3.1版本,如果發現一些代碼運行不正確或效果圖有變化,應該是版本不同造成。文章後都有sessionInfo信息可參考。
sessionInfo()
## R version 3.0.1 (2013-05-16)
## Platform: x86_64-pc-linux-gnu (64-bit)
## ## locale:
## [1] LC_CTYPE=zh_CN.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=zh_CN.UTF-8 LC_COLLATE=zh_CN.UTF-8
## [5] LC_MONETARY=zh_CN.UTF-8 LC_MESSAGES=zh_CN.UTF-8
## [7] LC_PAPER=C LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C #
# [11] LC_MEASUREMENT=zh_CN.UTF-8 LC_IDENTIFICATION=C
## ## attached base packages:
## [1] grid tcltk stats graphics grDevices utils datasets
## [8] methods base ## ## other attached packages:
## [1] zblog_0.0.1 knitr_1.3.5 ggplot2_0.9.3.1
## ## loaded via a namespace (and not attached):
## [1] colorspace_1.2-2 dichromat_2.0-0 digest_0.6.3
## [4] evaluate_0.4.4 formatR_0.8 gtable_0.1.2
## [7] highr_0.1.2 labeling_0.2 MASS_7.3-27
## [10] munsell_0.4.2 plyr_1.8 proto_0.3-10
## [13] RColorBrewer_1.0-5 reshape2_1.2.2 scales_0.2.3
## [16] stringr_0.6.2 tools_3.0.1
ggplot2作圖詳解7(完):主題(theme)設置