隨著ggplot2的粘滯性越來越強(qiáng),用它來完成一張草圖已經(jīng)不能滿足人們?nèi)找嬖鲩L的愛美之心了。其實(shí)ggplot2就是為美圖而生的蒸眠,為此甚至不惜從新定義了一套繪圖語法。他當(dāng)然有能力把我們送的更遠(yuǎn)杆融,不過要花我們的時(shí)間來看看如何自定義繪圖主題楞卡。
本文原文如下:
先看一下默認(rèn)主題是怎樣的:
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"
)
您可以立即看到這是一個(gè)ggplot2可視化,因?yàn)樗谢疑拿姘灞尘捌⑿DJ(rèn)主題的一個(gè)常見問題是axis文本太小蒋腮。元素之間幾乎沒有任何空間。因此藕各,可視化看起來非常密集池摧。要更改可視化,我們首先需要了解在ggplot2中主題化是如何工作的激况。我們的目標(biāo)是為所有可視化編寫一個(gè)全局主題作彤,這樣我們就不必為每個(gè)可視化調(diào)整主題膘魄。
可以使用theme_get函數(shù)查看默認(rèn)主題的所有設(shè)計(jì)。該函數(shù)返回一個(gè)非常長的字符串宦棺,因此我們只看一些設(shè)計(jì)元素瓣距。完整的列表,您可以查看官方文檔代咸。讓我們從軸文本開始:
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個(gè)元素蹈丸。可以看到文本顏色設(shè)置為灰色呐芥。另外逻杖,字體大小設(shè)置為‘rel num 0.8’。Rel表示文本的大小是相對(duì)于相應(yīng)的父元素定義的,父元素是層次較高的元素思瘟。例如荸百,如果您在文本元素中全局定義文本大小,您將指定文本應(yīng)該只有父元素的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"
既然我們已經(jīng)知道了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)) )
這個(gè)過程只對(duì)單獨(dú)的可視化有意義。然而光绕,有些設(shè)計(jì)元素我們總是想要改變女嘲。例如,我們希望在每個(gè)可視化周圍添加填充诞帐,這樣文本就不會(huì)太靠近邊緣欣尼。我們也想使用我們學(xué)院的企業(yè)設(shè)計(jì)的某種字體。因此停蕉,我們必須找到全局定義樣式的方法愕鼓。
要全局定義主題,我們首先可以使用預(yù)定義的主題慧起。一種可能性是使用來自其他開發(fā)人員的包菇晃。例如,我是ggthemr包的粉絲蚓挤。要使用其中一個(gè)主題谋旦,你只需要添加一行代碼:
ggthemr('fresh', text_size = 18, layout = "scientific")
# Code for the plot goes here
這種可視化已經(jīng)看起來好多了。文本更大屈尼,更易讀册着。此外,可視化有自己的風(fēng)格脾歧,這是明確可識(shí)別的甲捏。然而,并不是所有元素都按照您希望的方式設(shè)計(jì)鞭执。例如司顿,我希望將右下角的標(biāo)題用較小的字體顯示芒粹,并使標(biāo)題的顏色更暗。
我們的問題的解決方案是函數(shù)theme_set大溜。使用theme_set化漆,我們可以定義自己的主題,并將其全局應(yīng)用于所有可視化钦奋。全局更改主題的最簡單方法是使用ggplot2的一個(gè)預(yù)定義主題.
theme_set(theme_minimal(base_size = 18))# Code for the plot goes here
我們使用的第一個(gè)技巧是更改文本大小座云。ggplot2中的每個(gè)預(yù)定義主題都有base_size參數(shù),我們可以使用它來更改文本大小付材。其他所有樣式都是由theme_minimum函數(shù)設(shè)置的朦拖。有了這個(gè)函數(shù),我們現(xiàn)在可以通過添加函數(shù)主題來設(shè)計(jì)每個(gè)元素厌衔。在下一個(gè)示例中璧帝,我們將使用繪圖為整個(gè)可視化添加填充。
theme_set(theme_minimal(base_size = 18) +
theme(
plot.margin = unit(rep(1, 4), "cm")
))
# Code for the plot goes here
修改圖中的字體也許太煩人了富寿,好在那是曾經(jīng)睬隶。我們還可以使用extrafont包更改可視化的字體。首先页徐,我們必須執(zhí)行函數(shù)font_import()來查找筆記本電腦上的所有字體。你只需要執(zhí)行這個(gè)函數(shù)一次泞坦。然后使用loadfonts()函數(shù)加載字體。您可以使用fonts()獲得所有字體的列表∽┣辏現(xiàn)在你可以選擇任何字體從這個(gè)列表和使用任何字體在你的主題:
#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
現(xiàn)在我們知道了如何全局更改元素贰锁,可以創(chuàng)建自己的主題了。在下一個(gè)示例中滤蝠,您可以找到我設(shè)計(jì)的主題豌熄。我確保元素之間有足夠的空白,并且字體足夠大物咳,所有讀者都可以閱讀锣险。我還將主題放在一個(gè)函數(shù)中,以便您以后可以輕松地在不同的主題之間切換览闰。
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
對(duì)于可視化芯肤,我使用字體Segoe。現(xiàn)在您已經(jīng)了解了原理压鉴,您可以根據(jù)自己的喜好定制主題崖咨。我發(fā)現(xiàn)寫一個(gè)適用于所有可視化的基本主題是很方便的。其他主題都是基于基本主題油吭。例如击蹲,在接下來的可視化中署拟,我嘗試從ggthemr包中重新創(chuàng)建一個(gè)主題:
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
從代碼中可以看到,我已經(jīng)將flat_theme添加到了base_theme中歌豺。兩個(gè)變量都包含主題函數(shù)推穷。原則上,我還可以添加第三個(gè)主題类咧。在上一個(gè)例子中馒铃,我創(chuàng)建了一個(gè)全局黑暗主題:
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()
對(duì)于暗主題,我們必須更改geoms以使可視化變得可讀轮听。在本例中骗露,我用淺綠色對(duì)箱形圖進(jìn)行了樣式設(shè)置。注意血巍,我還使用theme函數(shù)在可視化代碼中更改了主題萧锉,因?yàn)椴⒉皇撬械目梢暬亩夹枰侨值摹@缡龉眩覜Q定只在x軸上顯示網(wǎng)格:
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()
)
下一步柿隙,我建議您嘗試使用此模板并創(chuàng)建自己的自定義主題。創(chuàng)建您自己的主題可能會(huì)花費(fèi)您一些工作鲫凶,但是稍后您將不必為每個(gè)單獨(dú)的可視化定制主題禀崖。您可能仍然想知道在哪里存儲(chǔ)這些主題,而不必編寫包螟炫。一個(gè)解決方案是將你的主題復(fù)制到每一個(gè)r文件波附,但這將是重復(fù)的。我建議您在項(xiàng)目中創(chuàng)建一個(gè)單獨(dú)的文件來存儲(chǔ)主題昼钻。你可以把這個(gè)文件讀入R后使用的源函數(shù):
source("set_themes.R")
思考掸屡,如果設(shè)置了全局主題,如何在應(yīng)用避免他呢然评,如果我想的話仅财?
ggthemr_reset()