ggplot2自定义绘图主题

随着ggplot2的粘滞性越来越强,用它来完成一张草图已经不能满足人们日益增长的爱美之心了。其实ggplot2就是为美图而生的,为此甚至不惜从新定义了一套绘图语法。他当然有能力把我们送的更远,不过要花我们的时间来看看如何自定义绘图主题。

本文原文如下:

请进

先看一下默认主题是怎样的:

The default theme
library(tidyverse)

ggplot(mpg, aes(x = class, y = cty)) +
  geom_boxplot(fill = "#6CB2EB", color = "#22292F",
               alpha = .8) +
  labs(
    title = "Stet clita kasd gubergren",
    subtitle = str_wrap(paste("Lorem ipsum dolor sit amet,",
                              "consetetur sadipscing elitr, sed diam",
                              "nonumy eirmod tempor invidunt ut labore",
                              "et dolore magna aliquyam erat, sed diam voluptua."), 
                        width = 80),
    caption = "Data: ggplot2; Visualization by Christian Burkhart"
  ) 

您可以立即看到这是一个ggplot2可视化,因为它有灰色的面板背景。默认主题的一个常见问题是axis文本太小。元素之间几乎没有任何空间。因此,可视化看起来非常密集。要更改可视化,我们首先需要了解在ggplot2中主题化是如何工作的。我们的目标是为所有可视化编写一个全局主题,这样我们就不必为每个可视化调整主题。

可以使用theme_get函数查看默认主题的所有设计。该函数返回一个非常长的字符串,因此我们只看一些设计元素。完整的列表,您可以查看官方文档。让我们从轴文本开始:

theme_get()$axis.text
List of 11
 $ family       : NULL
 $ face         : NULL
 $ colour       : chr "grey30"
 $ size         : 'rel' num 0.8
 $ hjust        : NULL
 $ vjust        : NULL
 $ angle        : NULL
 $ lineheight   : NULL
 $ margin       : NULL
 $ debug        : NULL
 $ inherit.blank: logi TRUE
 - attr(*, "class")= chr [1:2] "element_text" "element"

axis文本总共有11个元素。可以看到文本颜色设置为灰色。另外,字体大小设置为‘rel num 0.8’。Rel表示文本的大小是相对于相应的父元素定义的,父元素是层次较高的元素。例如,如果您在文本元素中全局定义文本大小,您将指定文本应该只有父元素的80%大(更多信息可以在这里找到,here
)。

 theme_get()$panel.background:

List of 5
 $ fill         : chr "grey92"
 $ colour       : logi NA
 $ size         : NULL
 $ linetype     : NULL
 $ inherit.blank: logi TRUE
 - attr(*undefined "class")= chr [1:2] "element_rect" "element"

既然我们已经知道了ggpplot2 主题的基本逻辑就可以开始我们的想象力了。

Set a global theme
ggplot(mpg, aes(x = class, y = cty)) +
  geom_boxplot(fill = "#6CB2EB", color = "#22292F",
               alpha = .8) +
  labs(
    title = "Stet clita kasd gubergren",
    subtitle = str_wrap(paste("Lorem ipsum dolor sit amet,",
                              "consetetur sadipscing elitr, sed diam",
                              "nonumy eirmod tempor invidunt ut labore",
                              "et dolore magna aliquyam erat, sed diam voluptua."), 
                        width = 80),
    caption = "Data: ggplot2; Visualization by Christian Burkhart"
  ) +
  theme(    panel.background = element_rect(color = "steelblue"),    axis.text        = element_text(size = rel(1.2))  )

这个过程只对单独的可视化有意义。然而,有些设计元素我们总是想要改变。例如,我们希望在每个可视化周围添加填充,这样文本就不会太靠近边缘。我们也想使用我们学院的企业设计的某种字体。因此,我们必须找到全局定义样式的方法。

要全局定义主题,我们首先可以使用预定义的主题。一种可能性是使用来自其他开发人员的包。例如,我是ggthemr包的粉丝。要使用其中一个主题,你只需要添加一行代码:

ggthemr('fresh', text_size = 18, layout = "scientific")
# Code for the plot goes here

这种可视化已经看起来好多了。文本更大,更易读。此外,可视化有自己的风格,这是明确可识别的。然而,并不是所有元素都按照您希望的方式设计。例如,我希望将右下角的标题用较小的字体显示,并使标题的颜色更暗。

我们的问题的解决方案是函数theme_set。使用theme_set,我们可以定义自己的主题,并将其全局应用于所有可视化。全局更改主题的最简单方法是使用ggplot2的一个预定义主题.

theme_set(theme_minimal(base_size = 18))# Code for the plot goes here

我们使用的第一个技巧是更改文本大小。ggplot2中的每个预定义主题都有base_size参数,我们可以使用它来更改文本大小。其他所有样式都是由theme_minimum函数设置的。有了这个函数,我们现在可以通过添加函数主题来设计每个元素。在下一个示例中,我们将使用绘图为整个可视化添加填充。

theme_set(theme_minimal(base_size = 18) +
            theme(
              plot.margin = unit(rep(1, 4), "cm")
            ))
# Code for the plot goes here

修改图中的字体也许太烦人了,好在那是曾经。我们还可以使用extrafont包更改可视化的字体。首先,我们必须执行函数font_import()来查找笔记本电脑上的所有字体。你只需要执行这个函数一次。然后使用loadfonts()函数加载字体。您可以使用fonts()获得所有字体的列表。现在你可以选择任何字体从这个列表和使用任何字体在你的主题:

#install.packages('extrafont')
library(extrafont)
font_import() # Run only once

#Continue? [y/n] y
#Scanning ttf files in C:\WINDOWS\Fonts ...
#Extracting .afm files from .ttf files...
#C:\Windows\Fonts\arial.ttf => E:/software/R/R-3.6.2/library/extrafontdb/metrics/arial
#C:\Windows\Fonts\arialbd.ttf => E:/software/R/R-3.6.2/library/extrafontdb/metrics/arialbd
#C:\Windows\Fonts\arialbi.ttf => E:/software/R/R-3.6.2/library/extrafontdb/metrics/arialbi

loadfonts() # Run only once
fonts() # Show a list of all fonts
 [1] "Arial Black"             "Arial"                   "Bahnschrift"             "Calibri"                 "Calibri Light"           "Cambria"                
 [7] "Candara"                 "Candara Light"           "Comic Sans MS"           "Consolas"                "Constantia"              "Corbel"                 
[13] "Corbel Light"            "Courier New"             "DejaVu Sans Mono"        "DengXian"                "DengXian Light"          "Ebrima"                 
[19] "FangSong"                "Franklin Gothic Medium"  "FZCuHeiSongS-B-GB"       "Gabriola"                "Gadugi"                  "Georgia"                
[25] "HoloLens MDL2 Assets"    "HP Simplified"           "HP Simplified Light"     "Impact"                  "Ink Free"                "Javanese Text"          
[31] "KaiTi"                   "Leelawadee UI"           "Leelawadee UI Semilight" "Lucida Console"          "Lucida Sans Unicode"     "Malgun Gothic"          
[37] "Malgun Gothic Semilight" "Marlett"                 "Microsoft Himalaya"      "Microsoft Yi Baiti"      "Microsoft New Tai Lue"   "Microsoft PhagsPa"      
[43] "Microsoft Sans Serif"    "Microsoft Tai Le"        "Mongolian Baiti"         "MV Boli"                 "Myanmar Text"            "Nirmala UI"             
[49] "Nirmala UI Semilight"    "NumberOnly"              "Palatino Linotype"       "Segoe MDL2 Assets"       "Segoe Print"             "Segoe Script"           
[55] "Segoe UI"                "Segoe UI Light"          "Segoe UI Semibold"       "Segoe UI Semilight"      "Segoe UI Black"          "Segoe UI Emoji"         
[61] "Segoe UI Historic"       "Segoe UI Symbol"         "SimHei"                  "SimSun-ExtB"             "Sylfaen"                 "Symbol"                 
[67] "Tahoma"                  "Times New Roman"         "Trebuchet MS"            "Verdana"                 "Webdings"                "Wingdings"              
> theme_set(theme_minimal(base_size = 18, 

theme_set(theme_minimal(base_size = 18, 
base_family = "Segoe UI") +            theme(
  plot.margin = unit(rep(1, 4), "cm")
))
# Code for the plot goes here
Create your own global themes

现在我们知道了如何全局更改元素,可以创建自己的主题了。在下一个示例中,您可以找到我设计的主题。我确保元素之间有足够的空白,并且字体足够大,所有读者都可以阅读。我还将主题放在一个函数中,以便您以后可以轻松地在不同的主题之间切换。

base_theme <- theme(
  plot.margin = unit(rep(1, 4), "cm"),
  plot.title = element_text(size = 24, 
                            face = "bold",
                            color = "#22292F", 
                            margin = margin(b = 8)),
  plot.subtitle = element_text(size = 16, 
                               lineheight = 1.1,
                               color = "#22292F",
                               margin = margin(b = 25)),
  plot.caption = element_text(size = 12,
                              margin = margin(t = 25), 
                              color = "#3D4852"),
  axis.title.x = element_text(margin = margin(t = 15)),
  axis.title.y = element_text(margin = margin(r = 15)),
  axis.text = element_text(color = "#22292F")
) 

set_base_theme <- function() {
  theme_set(theme_minimal(base_size = 18) +
              base_theme)
}
set_base_theme()
# Code for the plot goes here

对于可视化,我使用字体Segoe。现在您已经了解了原理,您可以根据自己的喜好定制主题。我发现写一个适用于所有可视化的基本主题是很方便的。其他主题都是基于基本主题。例如,在接下来的可视化中,我尝试从ggthemr包中重新创建一个主题:

flat_theme <- theme(
  panel.background = element_rect(fill = "#f3f6f6", color = NA),
  panel.grid = element_line(color = "#cacfd2", linetype = "dashed"),
  axis.line = element_line(color = "#606F7B")
)

set_flat_theme <- function() {
  theme_set(theme_minimal(base_size = 18) +
              base_theme +
              flat_theme)
}

set_flat_theme()
# Code for the plot goes here

从代码中可以看到,我已经将flat_theme添加到了base_theme中。两个变量都包含主题函数。原则上,我还可以添加第三个主题。在上一个例子中,我创建了一个全局黑暗主题:

dark_theme <- theme(
  plot.margin = unit(rep(1, 4), "cm"),
  plot.title = element_text(size = 24, 
                            face = "bold",
                            color = "#22292F", 
                            margin = margin(b = 8)),
  plot.subtitle = element_text(size = 16, 
                               lineheight = 1.1,
                               color = "#22292F",
                               margin = margin(b = 25)),
  plot.caption = element_text(size = 12,
                              margin = margin(t = 25), 
                              color = "#3D4852"),
  axis.title.x = element_text(margin = margin(t = 15)),
  axis.title.y = element_text(margin = margin(r = 15)),
  axis.text = element_text(color = "#22292F"),
  panel.background = element_rect("#34495e", color = NA),
  panel.grid = element_line(color = "#49637a")
) 

set_dark_theme <- function() {
  theme_set(theme_minimal(base_size = 18,
                          base_family = "Segoe UI") +
              dark_theme)
}
set_dark_theme()

对于暗主题,我们必须更改geoms以使可视化变得可读。在本例中,我用浅绿色对箱形图进行了样式设置。注意,我还使用theme函数在可视化代码中更改了主题,因为并不是所有的可视化更改都需要是全局的。例如,我决定只在x轴上显示网格:

ggplot(mpg, aes(x = class, y = cty)) +
  geom_boxplot(fill = "#64D5CA", color = "#ffffff",
               alpha = .8) +
  labs(
    title = "Stet clita kasd gubergren",
    subtitle = str_wrap(paste("Lorem ipsum dolor sit amet,",
                              "consetetur sadipscing elitr, sed diam",
                              "nonumy eirmod tempor invidunt ut labore",
                              "et dolore magna aliquyam erat, sed diam voluptua."), 
                        width = 80),
    caption = "Data: ggplot2; Visualization by Christian Burkhart"
  ) +
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.minor.y = element_blank()
  )

下一步,我建议您尝试使用此模板并创建自己的自定义主题。创建您自己的主题可能会花费您一些工作,但是稍后您将不必为每个单独的可视化定制主题。您可能仍然想知道在哪里存储这些主题,而不必编写包。一个解决方案是将你的主题复制到每一个r文件,但这将是重复的。我建议您在项目中创建一个单独的文件来存储主题。你可以把这个文件读入R后使用的源函数:

source("set_themes.R")

思考,如果设置了全局主题,如何在应用避免他呢,如果我想的话?

ggthemr_reset()

ggthemr 知乎

你可能感兴趣的:(ggplot2自定义绘图主题)