根据构面的存在条件有条件地修改ggplot主题? [英] Conditionally modify ggplot theme based on presence of facets?
问题描述
我正在研究自定义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屋!