ggplot_theme.md 16 KB

主题(theme)

theme函数

主题是一系列外观参数的组合,主题有一定的风格,要求个部分颜色、大小、字体、风格协调,给人一种美感。有些是具体的应用场景决定的,比如科技论文要求黑白风格的图表样式,有些期刊对字体和刻度尺有着特殊的要求,而在作报告是又会选择有颜色的图表风格。主题设置图表的整体或者综合的外观(aspect),也可以叫做图表的风格。比如线的粗细、字体大小、颜色等等。

一些参数设置是比较繁琐的,设定之后就可以作为主题固定下来,下次使用时直接应用主题就可以了。主题可以让科研人员在数据分析阶段能专注于数据而不是图形细节。

用法和参数

theme_grey(base_size = 11, base_family = "")

theme_gray(base_size = 11, base_family = "")

theme_bw(base_size = 12, base_family = "")

theme_linedraw(base_size = 12, base_family = "")

theme_light(base_size = 12, base_family = "")

theme_minimal(base_size = 12, base_family = "")

theme_classic(base_size = 12, base_family = "")

theme_dark(base_size = 12, base_family = "")

theme_void(base_size = 12, base_family = "")

参数 base_size:基本文字大小,标题字体、标签字体、坐标轴字体等如果没有设定,则用基本文字大小。
base_family:基本字体。
...: dotdotdot参数:
element_line,element_rect,element_text和element_blank函数设置,使用方法参考这几个函数的参数说明即可。 text, line, rect和title是最顶层的元素,类似于抽象类,无法直接设定,可通过其子函数设置。

x <- LETTERS[1:10]
y <- abs(rnorm(10))
thm<-  theme(
    text = element_text(color = "red", size = 16), 
    line = element_line(color = "blue"), 
    rect = element_rect(fill = "white"))
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") 
    + thm

p + theme(
        panel.background = element_rect(fill = "transparent", color = "gray"),
        legend.key = element_rect(fill = "transparent", color = "transparent"),
        axis.text = element_text(color = "red"))
参数 内容 继承自
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

ggplot2图形元素属性设置

theme_bw()函数输出可以看出主题元素及其参数和默认设置:

基本对象
  • line ..$ colour : chr "black"
    ..$ size : num 0.5
    ..$ linetype: num 1
    ..$ lineend : chr "butt"
    ..- attr(*, "class")= chr [1:2] "element_line" "element"
  • rect :List of 4
    ..$ fill : chr "white"
    ..$ colour : chr "black"
    ..$ size : num 0.5
    ..$ linetype: num 1
    ..- attr(*, "class")= chr [1:2] "element_rect" "element"
  • text :List of 10
    ..$ family : chr ""
    ..$ face : chr "plain"
    ..$ colour : chr "black"
    ..$ size : num 12
    ..$ hjust : num 0.5
    ..$ vjust : num 0.5
    ..$ angle : num 0
    ..$ lineheight: num 0.9
    ..$ margin :Classes 'margin', 'unit' atomic [1:4] 0 0 0 0
    .. .. ..- attr(, "unit")= chr "pt"
    .. .. ..- attr(
    , "valid.unit")= int 8
    ..$ debug : logi FALSE
    ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • axis.line :List of 4
    ..$ colour : NULL
    ..$ size : NULL
    ..$ linetype: NULL
    ..$ lineend : NULL
    ..- attr(*, "class")= chr [1:2] "element_line" "element"

  • axis.line.x : list()
    ..- attr(*, "class")= chr [1:2] "element_blank" "element"

  • axis.line.y : list()
    ..- attr(*, "class")= chr [1:2] "element_blank" "element"

  • axis.text :List of 10
    ..$ family : NULL
    ..$ face : NULL
    ..$ colour : NULL
    ..$ size :Class 'rel' num 0.8
    ..$ hjust : NULL
    ..$ vjust : NULL
    ..$ angle : NULL
    ..$ lineheight: NULL
    ..$ margin : NULL
    ..$ debug : NULL
    ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • axis.text.x :List of 10
    ..$ family : NULL
    ..$ face : NULL
    ..$ colour : NULL
    ..$ size : NULL
    ..$ hjust : NULL
    ..$ vjust : num 1
    ..$ angle : NULL
    ..$ lineheight: NULL
    ..$ margin :Classes 'margin', 'unit' atomic [1:4] 2.4 0 0 0
    .. .. ..- attr(, "unit")= chr "pt"
    .. .. ..- attr(
    , "valid.unit")= int 8
    ..$ debug : NULL
    ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • axis.text.y :List of 10
    ..$ family : NULL
    ..$ face : NULL
    ..$ colour : NULL
    ..$ size : NULL
    ..$ hjust : num 1
    ..$ vjust : NULL
    ..$ angle : NULL
    ..$ lineheight: NULL
    ..$ margin :Classes 'margin', 'unit' atomic [1:4] 0 2.4 0 0
    .. .. ..- attr(, "unit")= chr "pt"
    .. .. ..- attr(
    , "valid.unit")= int 8
    ..$ debug : NULL
    ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • axis.ticks :List of 4
    ..$ colour : chr "black"
    ..$ size : NULL
    ..$ linetype: NULL
    ..$ lineend : NULL
    ..- attr(*, "class")= chr [1:2] "element_line" "element"

  • axis.ticks.length :Class 'unit' atomic [1:1] 3
    .. ..- attr(, "unit")= chr "pt"
    .. ..- attr(
    , "valid.unit")= int 8

  • axis.title.x :List of 10
    ..$ family : NULL
    ..$ face : NULL
    ..$ colour : NULL
    ..$ size : NULL ..$ hjust : NULL ..$ vjust : NULL ..$ angle : NULL ..$ lineheight: NULL ..$ margin :Classes 'margin', 'unit' atomic [1:4] 4.8 0 2.4 0 .. .. ..- attr(, "unit")= chr "pt" .. .. ..- attr(, "valid.unit")= int 8 ..$ debug : NULL ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • axis.title.y :List of 10 ..$ family : NULL ..$ face : NULL ..$ colour : NULL ..$ size : NULL ..$ hjust : NULL ..$ vjust : NULL ..$ angle : num 90 ..$ lineheight: NULL ..$ margin :Classes 'margin', 'unit' atomic [1:4] 0 4.8 0 2.4 .. .. ..- attr(, "unit")= chr "pt" .. .. ..- attr(, "valid.unit")= int 8 ..$ debug : NULL ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • legend.background :List of 4 ..$ fill : NULL ..$ colour : logi NA ..$ size : NULL ..$ linetype: NULL ..- attr(*, "class")= chr [1:2] "element_rect" "element"

  • legend.margin :Class 'unit' atomic [1:1] 0.2 .. ..- attr(, "unit")= chr "cm" .. ..- attr(, "valid.unit")= int 1

  • legend.key :List of 4 ..$ fill : NULL ..$ colour : chr "grey80" ..$ size : NULL ..$ linetype: NULL ..- attr(*, "class")= chr [1:2] "element_rect" "element"

  • legend.key.size :Class 'unit' atomic [1:1] 1.2
    .. ..- attr(, "unit")= chr "lines"
    .. ..- attr(
    , "valid.unit")= int 3

  • legend.key.height : NULL

  • legend.key.width : NULL

  • legend.text :List of 10
    ..$ family : NULL
    ..$ face : NULL
    ..$ colour : NULL ..$ size :Class 'rel' num 0.8 ..$ hjust : NULL ..$ vjust : NULL ..$ angle : NULL ..$ lineheight: NULL ..$ margin : NULL ..$ debug : NULL ..- attr(, "class")= chr [1:2] "element_text" "element" $ legend.text.align : NULL $ legend.title :List of 10 ..$ family : NULL ..$ face : NULL ..$ colour : NULL ..$ size : NULL ..$ hjust : num 0 ..$ vjust : NULL ..$ angle : NULL ..$ lineheight: NULL ..$ margin : NULL ..$ debug : NULL ..- attr(, "class")= chr [1:2] "element_text" "element" $ legend.title.align : NULL $ legend.position : chr "right" $ legend.direction : NULL $ legend.justification : chr "center" $ legend.box : NULL

  • panel.background :List of 4 ..$ fill : chr "white" ..$ colour : logi NA ..$ size : NULL ..$ linetype: NULL ..- attr(*, "class")= chr [1:2] "element_rect" "element"

  • panel.border :List of 4 ..$ fill : logi NA ..$ colour : chr "grey50" ..$ size : NULL ..$ linetype: NULL ..- attr(*, "class")= chr [1:2] "element_rect" "element"

  • panel.grid.major :List of 4 ..$ colour : chr "grey90" ..$ size : num 0.2 ..$ linetype: NULL ..$ lineend : NULL ..- attr(*, "class")= chr [1:2] "element_line" "element"

  • panel.grid.minor :List of 4 ..$ colour : chr "grey98" ..$ size : num 0.5 ..$ linetype: NULL ..$ lineend : NULL ..- attr(*, "class")= chr [1:2] "element_line" "element"

  • panel.margin :Class 'unit' atomic [1:1] 6 .. ..- attr(, "unit")= chr "pt" .. ..- attr(, "valid.unit")= int 8 $ panel.margin.x : NULL $ panel.margin.y : NULL $ panel.ontop : logi FALSE

  • strip.background :List of 4 ..$ fill : chr "grey80" ..$ colour : chr "grey50" ..$ size : num 0.2 ..$ linetype: NULL ..- attr(*, "class")= chr [1:2] "element_rect" "element"

  • strip.text :List of 10 ..$ family : NULL ..$ face : NULL ..$ colour : chr "grey10" ..$ size :Class 'rel' num 0.8 ..$ hjust : NULL ..$ vjust : NULL ..$ angle : NULL ..$ lineheight: NULL ..$ margin : NULL ..$ debug : NULL ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • strip.text.x :List of 10 ..$ family : NULL ..$ face : NULL ..$ colour : NULL ..$ size : NULL ..$ hjust : NULL ..$ vjust : NULL ..$ angle : NULL ..$ lineheight: NULL ..$ margin :Classes 'margin', 'unit' atomic [1:4] 6 0 6 0 .. .. ..- attr(, "unit")= chr "pt" .. .. ..- attr(, "valid.unit")= int 8 ..$ debug : NULL ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • strip.text.y :List of 10 ..$ family : NULL ..$ face : NULL ..$ colour : NULL ..$ size : NULL ..$ hjust : NULL ..$ vjust : NULL ..$ angle : num -90 ..$ lineheight: NULL ..$ margin :Classes 'margin', 'unit' atomic [1:4] 0 6 0 6 .. .. ..- attr(, "unit")= chr "pt" .. .. ..- attr(, "valid.unit")= int 8 ..$ debug : NULL ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • strip.switch.pad.grid:Class 'unit' atomic [1:1] 0.1 .. ..- attr(, "unit")= chr "cm" .. ..- attr(, "valid.unit")= int 1

  • strip.switch.pad.wrap:Class 'unit' atomic [1:1] 0.1 .. ..- attr(, "unit")= chr "cm" .. ..- attr(, "valid.unit")= int 1

  • plot.background :List of 4 ..$ fill : NULL ..$ colour : chr "white" ..$ size : NULL ..$ linetype: NULL ..- attr(*, "class")= chr [1:2] "element_rect" "element"

  • plot.title :List of 10 ..$ family : NULL ..$ face : NULL ..$ colour : NULL ..$ size :Class 'rel' num 1.2 ..$ hjust : NULL ..$ vjust : NULL ..$ angle : NULL ..$ lineheight: NULL ..$ margin :Classes 'margin', 'unit' atomic [1:4] 0 0 7.2 0 .. .. ..- attr(, "unit")= chr "pt" .. .. ..- attr(, "valid.unit")= int 8 ..$ debug : NULL ..- attr(*, "class")= chr [1:2] "element_text" "element"

  • plot.margin :Classes 'margin', 'unit' atomic [1:4] 6 6 6 6 .. ..- attr(, "unit")= chr "pt" .. ..- attr(, "valid.unit")= int 8

    • attr(*, "class")= chr [1:2] "theme" "gg"
    • attr(*, "complete")= logi TRUE
    • attr(*, "validate")= logi TRUE

ggplot2的预设主题。

library(ggplot2)
  • theme_gray:灰色主题,是ggplot2的默认主题,灰色背景,白色网格线。 {r} p + theme_gray()
  • theme_bw:黑白主题,经典亮底暗字主题,帮助文档中说用于投影仪投影效果更好。
p + theme_bw()

黑白主题是其他主题的基本主题,其他主题继承了黑白主题的图形参数设置并在其基础上定制。

  • theme_linedraw: 白底黑线。与黑白主题的应用场景类似,但该主题可能会绘制很细的线(小于1pt),不符合一些期刊的要求。 {r} p + theme_linedraw()
  • theme_light: 类似与theme_linedraw,但是线和坐标轴是浅灰色的,网格线和坐标轴更不显眼,数据显示部分更加突出强调。

    p + theme_light()
    
  • theme_dark: 与of theme_light类似, 线的尺寸相同,但使用暗背景。彩色的细线更容易看清楚。

    p + theme_dark()
    
  • theme_minimal: 没有背景和注解。

    p + theme_minimal()
    
  • theme_classic: 经典主题,有x轴和y轴,没有网格线。

    p + theme_classic()
    
  • theme_void: 空主题

p + theme_void()

自定义主题

图形细节设置虽然繁琐,但是在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后就可以直接调用:

```{r} 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")