你可以预先组成ggplot元素重复使用吗?

时间:2018-04-06 00:29:09

标签: r ggplot2

我正在创建几个共享常见图形元素的图表(例如,假设我希望所有图表上的x轴按特定顺序为类别,具有相同的轴标签,并且刻度标签始终旋转)。在ggplot2中,这意味着将以下术语添加到我的绘图对象中:

xlab("My axis title") + 
scale_x_discrete(limits=my_predefined_category_order) +
theme(axis.text.x=element_text(angle=90, vjust=0.5))

由于我将这些元素添加到几个图中,我想我会重构我的代码,所以我可以在一个地方更改它们。如果我将每个元素分配给它自己的函数,它就可以工作,如下所示:

my_xlab <- function() xlab("My axis title")
my_xlim <- function() scale_x_discrete(limits=my_predefined_category_order)
my_xrot <- function() theme(axis.text.x=element_text(angle=90, vjust=0.5))

接着是

mydata %>% 
    ggplot(aes(x=whatever, y=something)) +
    geom_point() + 
    my_xlab() + my_xlim() + my_xrot()

但我希望能够做的是将my_xlabmy_xlimmy_xrot合并到一个复合元素(称为my_xaxis)中同时设置所有三个图形元素。我试过这个:

my_xaxis <- function() my_xlab() %+% my_xlim() %+% my_xrot()

接着是

mydata %>% 
    ggplot(aes(x=whatever, y=something)) +
    geom_point() + 
    my_xaxis()

但它不起作用。然后我意识到%+%会返回NULL

class(ylim(0, 1))
# [1] "ScaleContinuousPosition" "ScaleContinuous" "Scale" "ggproto"
class(ylab("my ylabel"))
# [1] "labels"
class(ylim(0, 1) %+% ylab("my ylabel"))
# [1] "NULL"

这解释了为什么我尝试的东西不起作用。有没有办法达到我想要的目的?

1 个答案:

答案 0 :(得分:2)

关注this answer,您可以将所有这些放入列表中,然后通过+将其添加到您的地图中。此列表可以包含theme个元素。

my_xaxis = list(xlab("My axis title"),
             scale_x_discrete( limits = my_predefined_category_order ),
             theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) )

这是实践中的样子。

my_predefined_category_order = c("8", "6", "4")
my_xaxis = list(xlab("My axis title"),
             scale_x_discrete( limits = my_predefined_category_order ),
             theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) )

p = ggplot(mtcars, aes(x = factor(cyl), y = mpg)) +
    geom_point()
p + my_xaxis 

enter image description here