1. 程式人生 > >ggplot2作圖詳解7(完):主題(theme)設置

ggplot2作圖詳解7(完):主題(theme)設置

clas base 參數 由於 end 文字標簽 cut evaluate minor

凡是和數據無關的圖形設置內容理論上都可以歸為主題類,但考慮到一些內容(如坐標軸)的特殊性,可以允許例外的情況。主題的設置相當繁瑣,很容易就占用了 大量的作圖時間,應盡量把這些東西簡化,把註意力主要放在數據分析上。基於這種考慮,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)設置