我正在尝试编写一个自定义 ggplot 主题,如下所示https://joeystanley.com/blog/custom-themes-in-ggplot2/
这很简单,但我想增加一些复杂性,我的一些图只需要 X 轴上的网格线,而其他图只需要 Y 轴上的网格线(两者都不需要)。我想向主题函数添加一个参数来指定哪个是绘制轴,这样在图形脚本中,我可以调用
my_theme(gridline_axis = "x")
并让网格线仅在 x 轴上绘制。
但是,我一直无法弄清楚如何在 theme() 函数中添加条件参数。我相信挑战在于让条件语句作为主题的参数进行评估——尽管我尝试过 toString()、eval() 和 allocate()。
my_theme <- function(gridline_axis = "x") {
draw_axis = ifelse(gridline_axis == "x", yes = "x", no = "y")
blank_axis = ifelse(draw_axis == "x", yes = "y", no = "x")
my_theme = theme_bw(base_size = 12) %+replace%
theme(
#gridline settings -- user input of "x" produces major gridlines on the x axis and removes on Y axis
paste("panel.grid.major.",toString(blank_axis),sep = "") = element_blank(),
paste("panel.grid.minor.",toString(blank_axis),sep = "") = element_blank(),
paste("panel.grid.major.",toString(draw_axis),sep = "") = element_line(
color = "gray",
linewidth = 0.5,
linetype = 1
),
paste("panel.grid.minor.",toString(draw_axis),sep = "") = element_line(linetype = 1)
)
}
返回:
Error: unexpected '=' in:
" #gridline settings -- user input of "x" produces major gridlines on the x axis and removes on Y axis
toString(paste("panel.grid.major.",toString(blank_axis),sep = "")) ="
我还尝试在对 theme() 的主要调用中构建 if 语句——这是不成功的,因为它覆盖了 if 语句之外对 theme() 调用的任何内容。
我还尝试在我不想更改的主题部分之后使用 theme_set() ,然后根据我确实希望更改的部分的 if 语句使用 theme_update() 。虽然我不知道为什么,但失败了。
我试图通过基于 if else 语句完全复制 %+replace% 来避免重复我不想在任何绘图上更改的参数。
提前致谢
问题是您不能在
=
的左侧使用表达式。另外,虽然我总是试图避免重复代码,但对于当前的用例,我会使用像这样的 if-else
:
my_theme <- function(gridline_axis = "x") {
t <- theme_bw(base_size = 12)
grid_major <- element_line(
color = "gray",
linewidth = 0.5,
linetype = 1
)
grid_minor <- element_line(linetype = 1)
t <- t %+replace%
if (gridline_axis == "x") {
theme(
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank(),
panel.grid.major.x = grid_major,
panel.grid.minor.x = grid_minor
)
} else {
theme(
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
panel.grid.major.y = grid_major,
panel.grid.minor.y = grid_minor
)
}
t
}
library(ggplot2)
p <- ggplot(mtcars, aes(mpg, wt)) +
geom_point()
p +
my_theme()
p +
my_theme("y")
这里的第二种方法是使用
do.call
的选项,这可能更符合您想要实现的目标:
my_theme <- function(gridline_axis = "x") {
t <- theme_bw(base_size = 12)
draw_axis <- if (gridline_axis == "x") "x" else "y"
blank_axis <- if (gridline_axis == "x") "y" else "x"
panel_grid <- list(
element_blank(),
element_blank(),
element_line(
color = "gray",
linewidth = 0.5,
linetype = 1
),
element_line(linetype = 1)
)
names(panel_grid) <- c(
paste0("panel.grid.", c("minor", "major"), ".", blank_axis),
paste0("panel.grid.major.", draw_axis),
paste0("panel.grid.minor.", draw_axis)
)
t %+replace%
do.call(theme, args = panel_grid)
}
p +
my_theme()
p +
my_theme("y")