r - 根据构面的存在有条件地修改ggplot主题?
问题描述
我正在研究一个自定义的 ggplot2 主题,并认为根据绘图对象的某些特征自动修改主题元素可能很不错。例如,有没有办法指定如果绘图包含构面,则为每个面板添加边框?
我想问题是真的,我可以从自定义 theme() 调用中访问当前的 gg 对象,然后有条件地应用某些主题元素吗?在我的脑海中,我会将我的主题功能定义为:
theme_custom <- function() {
if (plot$facet$params > 0) {
theme_minimal() +
theme(panel.border = element_rect(color = "gray 50", fill = NA))
}
else {
theme_minimal()
}
}
如果这是可能的,它在使用中看起来像这样:
library(ggplot2)
# plot with facets automatically adds panel borders
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
facet_wrap(vars(cyl)) +
theme_custom()
# plot without facets no panel border
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
theme_custom()
注意:这最初是在RStudio 社区上发布的,但没有收到答案。
解决方案
我认为奥利弗的想法是正确的。
我不认为该theme_custom
函数是检查条件主题图的正确位置,因为主题函数大多不知道它们被添加到的精确图。
相反,我认为检查情节的适当位置是在情节中添加主题时。您可以编写如下所示的主题函数,为输出设置不同的类。
theme_custom <- function() {
out <- theme_minimal()
class(out) <- c("conditional_theme", class(out))
out
}
现在,每次将主题添加到情节时,都是通过函数完成的,我们可以为类ggplot_add.theme
重写。conditional_theme
在我看来,检查情节是否刻面的正确方法是检查插槽的类,当添加了适当的刻面时plot$facet
,可以是等,并且默认为未设置刻面时。FacetGrid
FacetWrap
FacetNull
ggplot_add.conditional_theme <- function(object, plot, object_name) {
if (!inherits(plot$facet, "FacetNull")) {
object <- object + theme(panel.border = element_rect(colour = "grey50", fill = NA))
}
plot$theme <- ggplot2:::add_theme(plot$theme, object, object_name)
plot
}
现在用例应该按预期工作:
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
facet_wrap(vars(cyl)) +
theme_custom()
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
theme_custom()
唯一的缺点是您每次都必须将主题添加到情节中,并且您不能使用 将theme_set(theme_custom())
其应用于会话中的任何情节。
推荐阅读
- microsoft-graph-api - 如何从标题中获取可用的电子邮件参考 ID 以在 Microsoft Graph 查询中使用?
- .htaccess - .htaccess 重定向不指向指定文件
- python - Keras(Tensorflow) python 图像分类与分析(根系统)
- sql - Postgresql 中使用触发器的总库存
- java - 使用自定义函数模拟静态 void 方法
- asp.net-core - Asp.Net 核心 ActionFilter 上下文请求正文已处理
- python - 堆叠从 Xarray 生成的 Dask 数组的有效方法
- java - 带有 OAuth 的 Spring Boot Security Multi Http 不起作用
- microsoft-edge - 发布 Microsoft Edge 扩展时如何解决识别问题?
- javascript - 等待函数解决没有参数的承诺