根据构面的存在条件有条件地修改ggplot主题? [英] Conditionally modify ggplot theme based on presence of facets?

查看:34
本文介绍了根据构面的存在条件有条件地修改ggplot主题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究自定义ggplot2主题,并认为根据plot对象的某些特征自动修改主题的元素可能很不错.例如,是否有一种方法可以指定如果绘图包含构面,请在每个面板上添加边框?

我想问题是真的,我可以在自定义theme()调用中访问当前的gg对象,然后有条件地应用某些主题元素吗?在我的脑海中,我将主题函数定义为如下形式:

  theme_custom<-function(){如果(plot $ facet $ params> 0){theme_minimal()+主题(panel.border = element_rect(颜色=灰色50",填充= NA))}别的 {theme_minimal()}} 

如果可能的话,它将看起来像这样:

 库(ggplot2)#具有刻面的绘图会自动添加面板边框ggplot(mtcars,aes(mpg,wt))+geom_point()+facet_wrap(vars(cyl))+theme_custom() 

 #没有刻面的图,没有面板边框ggplot(mtcars,aes(mpg,wt))+geom_point()+theme_custom() 

注意:这最初发布于

  ggplot(mtcars,aes(mpg,wt))+geom_point()+theme_custom() 

唯一的缺点是您每次都必须在主题上添加主题,并且不能使用 theme_set(theme_custom())将此主题应用于情节中的任何情节.会议.

I'm working on a custom ggplot2 theme and was thinking it could be nifty to automatically modify elements of the theme depending on certain characteristics of the the plot object. For instance, is there a way to specify that if the plot contains facets, add a border to each panel?

I guess the question is really, can I access the current gg object from within a custom theme() call and then conditionally apply certain theme elements? In my head I would define my theme function to be something like this:

theme_custom <- function() {
  if (plot$facet$params > 0) {
  theme_minimal() +
    theme(panel.border = element_rect(color = "gray 50", fill = NA))
  }
  else {
    theme_minimal()
    }
}

If this is possible, it would look like this in use:

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() 

NOTE: This was originally posted on RStudio Community and did not receive an answer.

解决方案

I think Oliver was thinking in the correct direction.

I don't think the theme_custom function is the correct place to check the plot for conditional theming, because theme functions are mostly agnostic about the precise plot that they are added to.

Instead, I think the appropriate place to check the plot is when the theme is added to the plot. You could write a theme function like the following, which sets a different class to the output.

theme_custom <- function() {
  out <- theme_minimal()
  class(out) <- c("conditional_theme", class(out))
  out
}

Now everytime a theme is added to a plot, this is done through the ggplot_add.theme function, which we can rewrite for the conditional_theme class. In my opinion, the correct way to check if a plot is facetted, is to check the class of the plot$facet slot, which can be FacetGrid, FacetWrap etc when a proper facet is added and defaults to FacetNull when no facet is set.

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
}

And now the use cases should work as intended:

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  facet_wrap(vars(cyl)) +
  theme_custom()

ggplot(mtcars, aes(mpg, wt)) +
  geom_point() +
  theme_custom() 

The only downside is that you would literally have to add the theme to the plot every time and you can't use the theme_set(theme_custom()) to have this apply to any plot in the session.

这篇关于根据构面的存在条件有条件地修改ggplot主题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆