如何分别格式化每个 ggplot 面板的轴刻度标签?
How can I format the axis tick labels for each ggplot panel separately?
我需要创建一个多面板图形,其中 y 轴(因子)的刻度标签对于某些面板是斜体,对于其他面板是纯文本。
这是一个可重现的例子,使用我试过的一件事的虚构数据:
library(ggplot2)
## Example data
df <- data.frame(var = c("Grass cover", "River depth", "Canis familiaris", "Canis lupus", "Canis latrans"),
coef = c(0.6, 0.4, 0.8, 0.1, 0.5),
se = c(0.3, 0.4, 0.4, 0.05, 0.2),
panel = c(rep("Environment", 2), rep("Canid abundance", 3)))
## multi-panel plot
ggplot(df, aes(y = var, x = coef, xmin = coef - se, xmax = coef + se)) +
geom_pointrange() +
facet_wrap(~ panel, scales = "free_y", ncol = 1) +
labs(y = NULL) +
theme(axis.text.y = element_text(face = c(rep("plain", 2), rep("italic", 3))))
请注意,只有“Canis lupus”在顶部面板中显示为斜体。所需的数字在第一个面板中的 all 科学名称(y 轴标签)是斜体,但底部面板中的标签应该是普通的。在真实数据中,我有4个面板,其中2个需要斜体。
element_text()
中的矢量化 face
参数似乎在面板之间循环使用。我也试过 axis.text.y = element_text(face = rep("italic", 3), c(rep("plain", 2)))
这导致所有 5 个 y 轴标签都被斜体化。
如果可能,我不想使用多个 ggplot 对象(即 grid_arrange()
或 cowplot()
)。不过,我愿意接受任何允许我调整所有视觉格式元素的解决方案。
我认为一定有使用expression()
的解决方案,但我一直无法解决。
实现您想要的结果的一个选择是使用 ggtext
包,它允许使用降价语法 and/or HTML/CSS 来设置标签和主题元素的样式。
- 利用
theme(axis.text.y = ggtext::element_markdown())
y 轴标签将被解析为降价代码。
- 将要显示为斜体的标签包裹在
* ... *
内。
library(ggplot2)
library(ggtext)
df <- data.frame(var = c("Grass cover", "River depth", "Canis familiaris", "Canis lupus", "Canis latrans"),
coef = c(0.6, 0.4, 0.8, 0.1, 0.5),
se = c(0.3, 0.4, 0.4, 0.05, 0.2),
panel = c(rep("Environment", 2), rep("Canid abundance", 3)))
df$var <- ifelse(df$panel %in% "Canid abundance", paste0("*", df$var, "*"), df$var)
## multi-panel plot
ggplot(df, aes(y = var, x = coef, xmin = coef - se, xmax = coef + se)) +
geom_pointrange() +
facet_wrap(~ panel, scales = "free_y", ncol = 1) +
labs(y = NULL) +
theme(axis.text.y = ggtext::element_markdown())
这是另一个选项。
library(tidyverse)
df <- tibble(var = c("Grass cover", "River depth", "Canis familiaris", "Canis lupus", "Canis latrans"),
coef = c(0.6, 0.4, 0.8, 0.1, 0.5),
se = c(0.3, 0.4, 0.4, 0.05, 0.2),
panel = c(rep("Environment", 2), rep("Canid abundance", 3)))
df %>%
mutate(lab = map2_chr(var, panel,
~ifelse(.y == "Canid abundance",
paste0('italic("', .x,'")'),
paste0('"', .x,'"')))) %>%
ggplot(aes(y = lab, x = coef, xmin = coef - se, xmax = coef + se)) +
geom_pointrange() +
facet_wrap(~ panel, scales = "free_y", ncol = 1) +
labs(y = NULL) +
scale_y_discrete(label = function(x) parse(text = x))
我需要创建一个多面板图形,其中 y 轴(因子)的刻度标签对于某些面板是斜体,对于其他面板是纯文本。
这是一个可重现的例子,使用我试过的一件事的虚构数据:
library(ggplot2)
## Example data
df <- data.frame(var = c("Grass cover", "River depth", "Canis familiaris", "Canis lupus", "Canis latrans"),
coef = c(0.6, 0.4, 0.8, 0.1, 0.5),
se = c(0.3, 0.4, 0.4, 0.05, 0.2),
panel = c(rep("Environment", 2), rep("Canid abundance", 3)))
## multi-panel plot
ggplot(df, aes(y = var, x = coef, xmin = coef - se, xmax = coef + se)) +
geom_pointrange() +
facet_wrap(~ panel, scales = "free_y", ncol = 1) +
labs(y = NULL) +
theme(axis.text.y = element_text(face = c(rep("plain", 2), rep("italic", 3))))
请注意,只有“Canis lupus”在顶部面板中显示为斜体。所需的数字在第一个面板中的 all 科学名称(y 轴标签)是斜体,但底部面板中的标签应该是普通的。在真实数据中,我有4个面板,其中2个需要斜体。
element_text()
中的矢量化 face
参数似乎在面板之间循环使用。我也试过 axis.text.y = element_text(face = rep("italic", 3), c(rep("plain", 2)))
这导致所有 5 个 y 轴标签都被斜体化。
如果可能,我不想使用多个 ggplot 对象(即 grid_arrange()
或 cowplot()
)。不过,我愿意接受任何允许我调整所有视觉格式元素的解决方案。
我认为一定有使用expression()
的解决方案,但我一直无法解决。
实现您想要的结果的一个选择是使用 ggtext
包,它允许使用降价语法 and/or HTML/CSS 来设置标签和主题元素的样式。
- 利用
theme(axis.text.y = ggtext::element_markdown())
y 轴标签将被解析为降价代码。 - 将要显示为斜体的标签包裹在
* ... *
内。
library(ggplot2)
library(ggtext)
df <- data.frame(var = c("Grass cover", "River depth", "Canis familiaris", "Canis lupus", "Canis latrans"),
coef = c(0.6, 0.4, 0.8, 0.1, 0.5),
se = c(0.3, 0.4, 0.4, 0.05, 0.2),
panel = c(rep("Environment", 2), rep("Canid abundance", 3)))
df$var <- ifelse(df$panel %in% "Canid abundance", paste0("*", df$var, "*"), df$var)
## multi-panel plot
ggplot(df, aes(y = var, x = coef, xmin = coef - se, xmax = coef + se)) +
geom_pointrange() +
facet_wrap(~ panel, scales = "free_y", ncol = 1) +
labs(y = NULL) +
theme(axis.text.y = ggtext::element_markdown())
这是另一个选项。
library(tidyverse)
df <- tibble(var = c("Grass cover", "River depth", "Canis familiaris", "Canis lupus", "Canis latrans"),
coef = c(0.6, 0.4, 0.8, 0.1, 0.5),
se = c(0.3, 0.4, 0.4, 0.05, 0.2),
panel = c(rep("Environment", 2), rep("Canid abundance", 3)))
df %>%
mutate(lab = map2_chr(var, panel,
~ifelse(.y == "Canid abundance",
paste0('italic("', .x,'")'),
paste0('"', .x,'"')))) %>%
ggplot(aes(y = lab, x = coef, xmin = coef - se, xmax = coef + se)) +
geom_pointrange() +
facet_wrap(~ panel, scales = "free_y", ncol = 1) +
labs(y = NULL) +
scale_y_discrete(label = function(x) parse(text = x))