本章是ggplot2科研绘图调参的第十二个章节,前十章内容请跳转:
数据集
本文使用 空气污染导致全国发病率和死亡率研究 (NMMAPS). 为了使图表易于管理,我们将数据限制在芝加哥和 1997-2000 年。有关此数据集的更多详细信息,请参阅 Roger Peng 的书 Statistical Methods in Environmental Epidemiology with R.
使用 {rio}
包中的 import函数
将数据导入到我们的 R 中。为了稍后访问数据,我们使用赋值箭头<-
将其存储在名为chic
的变量中。
library(tidyverse)
library(ggplot2)
theme_set(theme_bw())
library(rio)
chic <- import("/Users/cpf/Documents/paper/writting_blog/data/chicago-nmmaps.csv")
12.主题设置
ggplot2
包中默认带有包含如下图所示若干个主题设置,
12.1 主题包推荐
ggtheme
有几个包提供额外的主题,有些甚至有不同的默认调色板。例如,Jeffrey Arnold 将库 {ggthemes} 与几个模仿流行设计的自定义主题组合在一起。如需列表,您可以访问 ggthemes
(https://github.com/jrnold/ggthemes)。无需任何编码,您就可以找到多种主题风格。
以下是使用 theme_economist()
和 scale_color_economist()
复制 The Economist 杂志中的绘图样式的示例:
library(ggthemes)
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() +
labs(x = "Year" , y = "Temperature (°F)") +
ggtitle("Ups and Downs of Chicago's Daily Temperatures") +
theme_economist() +
scale_color_economist(name = NULL)
另一个例子是 Tufte 的绘图风格, Tufte 因其主题风格的纯粹而很受欢迎。
chic_2000 <- filter(chic, year == 2000)
ggplot(chic_2000, aes(x = temp, y = o3)) +
geom_point() +
labs(x = "Temperature (°F)", y = "Ozone") +
ggtitle("Temperature and Ozone Levels During the Year 2000 in Chicago") +
theme_tufte()
hrbrthemes
另一个带有现代主题和非默认字体预设的包是 hrbrthemes
包,它有几个浅色和深色主题:
library(hrbrthemes)
ggplot(chic, aes(x = temp, y = o3)) +
geom_point(aes(color = dewpoint), show.legend = FALSE) +
labs(x = "Temperature (°F)", y = "Ozone") +
ggtitle("Temperature and Ozone Levels in Chicago") +
theme_ipsum_pub()
ggsci
ggsci
()提供了一系列高质量的调色板,其灵感来自科学期刊、数据可视化库、科幻电影和电视节目中使用的颜色。 ggsci 中的调色板可用作 ggplot2 比例。对于所有调色板,相应的比例命名为:
- scale_color_palname()
- scale_fill_palname()
具体可参考此文档
library(ggsci)
g = ggplot(chic, aes(x = temp, y = o3)) +
geom_point(aes(color = dewpoint), show.legend = FALSE) +
labs(x = "Temperature (°F)", y = "Ozone") +
ggtitle("Temperature and Ozone Levels in Chicago")
library(gridExtra)
grid.arrange(g, (g+scale_fill_material()), nrow=1)
12.2 更改所有文本元素的字体
一次更改所有文本元素的设置非常容易。所有主题都带有一个名为 base_family
的参数:
g <- ggplot(chic, aes(x = date, y = temp)) +
geom_point(color = "firebrick") +
labs(x = "Year", y = "Temperature (°F)",
title = "Temperatures in Chicago")
g + theme_bw(base_family = "Hack") # 注意这里的字体必须你电脑里有,否则会报错
12.3 更改所有文本的大小
theme_\*()
函数还带有其他几个 base_*
参数。如果您仔细查看默认主题,您会注意到所有元素的大小都是相对于 base_size
的。因此,如果您想提高绘图的可读性,您可以简单地更改 base_size:
g + theme_bw(base_size = 15, base_family = "Hack")
12.4 更改所有 Line 和 Rect 元素的大小
g + theme_bw(base_line_size = 1, base_rect_size = 1)
12.5 创建你自己的主题
如果您想更改整个会话的主题,您可以像在 theme_set(theme_bw())
中一样使用 theme_set
。默认值称为 theme_gray
(或 theme_gray)。如果您想创建自己的自定义主题,可以直接从灰色主题中提取代码并进行修改。请注意,rel()
函数会更改相对于 base_size 的大小。
现在,让我们修改默认的主题功能,看看结果:
theme_custom <- function (base_size = 12, base_family = "Arial") {
half_line <- base_size/2
theme(
line = element_line(color = "black", size = .5,
linetype = 1, lineend = "butt"),
rect = element_rect(fill = "white", color = "black",
size = .5, linetype = 1),
text = element_text(family = base_family, face = "plain",
color = "black", size = base_size,
lineheight = .9, hjust = .5, vjust = .5,
angle = 0, margin = margin(), debug = FALSE),
axis.line = element_blank(),
axis.line.x = NULL,
axis.line.y = NULL,
axis.text = element_text(size = base_size * 1.1, color = "gray30"),
axis.text.x = element_text(margin = margin(t = .8 * half_line/2),
vjust = 1),
axis.text.x.top = element_text(margin = margin(b = .8 * half_line/2),
vjust = 0),
axis.text.y = element_text(margin = margin(r = .8 * half_line/2),
hjust = 1),
axis.text.y.right = element_text(margin = margin(l = .8 * half_line/2),
hjust = 0),
axis.ticks = element_line(color = "gray30", size = .7),
axis.ticks.length = unit(half_line / 1.5, "pt"),
axis.ticks.length.x = NULL,
axis.ticks.length.x.top = NULL,
axis.ticks.length.x.bottom = NULL,
axis.ticks.length.y = NULL,
axis.ticks.length.y.left = NULL,
axis.ticks.length.y.right = NULL,
axis.title.x = element_text(margin = margin(t = half_line),
vjust = 1, size = base_size * 1.3,
face = "bold"),
axis.title.x.top = element_text(margin = margin(b = half_line),
vjust = 0),
axis.title.y = element_text(angle = 90, vjust = 1,
margin = margin(r = half_line),
size = base_size * 1.3, face = "bold"),
axis.title.y.right = element_text(angle = -90, vjust = 0,
margin = margin(l = half_line)),
legend.background = element_rect(color = NA),
legend.spacing = unit(.4, "cm"),
legend.spacing.x = NULL,
legend.spacing.y = NULL,
legend.margin = margin(.2, .2, .2, .2, "cm"),
legend.key = element_rect(fill = "gray95", color = "white"),
legend.key.size = unit(1.2, "lines"),
legend.key.height = NULL,
legend.key.width = NULL,
legend.text = element_text(size = rel(.8)),
legend.text.align = NULL,
legend.title = element_text(hjust = 0),
legend.title.align = NULL,
legend.position = "right",
legend.direction = NULL,
legend.justification = "center",
legend.box = NULL,
legend.box.margin = margin(0, 0, 0, 0, "cm"),
legend.box.background = element_blank(),
legend.box.spacing = unit(.4, "cm"),
panel.background = element_rect(fill = "white", color = NA),
panel.border = element_rect(color = "gray30",
fill = NA, size = .7),
panel.grid.major = element_line(color = "gray90", size = 1),
panel.grid.minor = element_line(color = "gray90", size = .5,
linetype = "dashed"),
panel.spacing = unit(base_size, "pt"),
panel.spacing.x = NULL,
panel.spacing.y = NULL,
panel.ontop = FALSE,
strip.background = element_rect(fill = "white", color = "gray30"),
strip.text = element_text(color = "black", size = base_size),
strip.text.x = element_text(margin = margin(t = half_line,
b = half_line)),
strip.text.y = element_text(angle = -90,
margin = margin(l = half_line,
r = half_line)),
strip.text.y.left = element_text(angle = 90),
strip.placement = "inside",
strip.placement.x = NULL,
strip.placement.y = NULL,
strip.switch.pad.grid = unit(0.1, "cm"),
strip.switch.pad.wrap = unit(0.1, "cm"),
plot.background = element_rect(color = NA),
plot.title = element_text(size = base_size * 1.8, hjust = .5,
vjust = 1, face = "bold",
margin = margin(b = half_line * 1.2)),
plot.title.position = "panel",
plot.subtitle = element_text(size = base_size * 1.3,
hjust = .5, vjust = 1,
margin = margin(b = half_line * .9)),
plot.caption = element_text(size = rel(0.9), hjust = 1, vjust = 1,
margin = margin(t = half_line * .9)),
plot.caption.position = "panel",
plot.tag = element_text(size = rel(1.2), hjust = .5, vjust = .5),
plot.tag.position = "topleft",
plot.margin = margin(base_size, base_size, base_size, base_size),
complete = TRUE
)
}
通过面板和网格线的新外观以及轴刻度、文本和标题来查看修改后的美学:
theme_set(theme_custom())
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() + labs(x = "Year", y = "Temperature (°F)") + guides(color = FALSE)
强烈推荐这种改变情节设计的方式!它允许您通过更改一次来快速更改绘图的任何元素。您可以在几秒钟内以一致的样式绘制所有结果并使其适应其他需求(例如,具有更大字体或期刊要求的演示文稿)。
12.6 更新现有的主体
theme_custom <- theme_update(panel.background = element_rect(fill = "white"),
panel.grid.major = element_line(size = .5),
panel.grid.minor = element_blank())
ggplot(chic, aes(x = date, y = temp, color = season)) +
geom_point() + labs(x = "Year", y = "Temperature (°F)") + guides(color = FALSE)
12.7 我现在使用的主题设置供大家参考
theme_Publication <- function(base_size=14, base_family="Helvetica") {
library(grid)
library(ggthemes)
(theme_foundation(base_size=base_size, base_family=base_family)
+ theme(plot.title = element_text(face = "bold",
size = rel(1.2), hjust = 0.5),
text = element_text(),
panel.background = element_rect(colour = NA),
plot.background = element_rect(colour = NA),
panel.border = element_rect(colour = NA),
axis.title = element_text(face = "bold",size = rel(1)),
axis.title.y = element_text(angle=90,vjust =2),
axis.title.x = element_text(vjust = -0.2),
axis.text = element_text(),
axis.line = element_line(colour="black"),
axis.ticks = element_line(),
panel.grid.major = element_line(colour="#f0f0f0"),
panel.grid.minor = element_blank(),
legend.key = element_rect(colour = NA),
legend.position = "bottom",
legend.direction = "horizontal",
legend.key.size= unit(0.2, "cm"),
legend.margin = unit(0, "cm"),
legend.title = element_text(face="italic"),
plot.margin=unit(c(10,5,5,5),"mm"),
strip.background=element_rect(colour="#f0f0f0",fill="#f0f0f0"),
strip.text = element_text(face="bold")
))
}
scale_fill_Publication <- function(...){
library(scales)
discrete_scale("fill","Publication",manual_pal(values = c("#386cb0","#fdb462","#7fc97f","#ef3b2c","#662506","#a6cee3","#fb9a99","#984ea3","#ffff33")), ...)
}
scale_colour_Publication <- function(...){
library(scales)
discrete_scale("colour","Publication",manual_pal(values = c("#386cb0","#fdb462","#7fc97f","#ef3b2c","#662506","#a6cee3","#fb9a99","#984ea3","#ffff33")), ...)
}
library(patchwork)
grid.arrange((g+ theme_bw()), (g + scale_colour_Publication() + theme_Publication()), nrow = 1)