I want to define a common style for all my plots, and I found that defining a custom theme is very useful. However, I would also like to define default values for variables that are not in themes, such as the size of lines and the widths of bars in geom_barplot
, or expand
in scale_y_continuous
.
To be more specific, I defined my custom theme so that in barplots the x-axis should be at zero, so I set scale_y_continuous(expand=c(0,0))
, but I have to do it "by hand" every time I call ggplot
. Is there a way to redefine default values for this and other variables once and for all plots, similarly to what I can do with variables in themes?
CodePudding user response:
There are several ways of doing this, though to get the syntax as simple as mytheme
would require a bit of work, including creating a new class to hold theme and scale elements, and over-riding the .gg
method, which I don't personally think is worth the trouble:
make_mytheme <- function(scale, theme) {
structure(list(scale = scale, theme = theme), class = 'mythemeclass')
}
` .gg` <- function(e1, e2) {
e2name <- deparse(substitute(e2))
if(inherits(e2, 'mythemeclass')) {
e1 <- ggplot2:::add_ggplot(e1, e2$scale, e2name)
return(ggplot2:::add_ggplot(e1, e2$theme, e2name))
} else {
return(ggplot2:::` .gg`(e1, e2))
}
}
You can now create a theme that you can use which incorporates scale items and theme items:
mytheme <- make_mytheme(scale_y_continuous(expand = c(0, 0)),
theme_bw(base_size = 20))
So, for example, if we had the following plot:
p <- ggplot(mtcars, aes(gear, mpg))
geom_bar(stat = 'summary', fun = mean)
p
We could just do:
p mytheme
A simpler way would be to create a wrapper around ggplot itself:
my_ggplot <- function(...) {
ggplot(...)
scale_y_continuous(expand = c(0, 0))
theme_bw(base_size = 20)
}
Which allows:
my_ggplot(mtcars, aes(gear, mpg))
geom_bar(stat = 'summary', fun = mean)
Changing the default line thickness of the various geoms can easily be done with similar wrappers, for example:
geom_thickline <- function(...) geom_line(..., size = 2)
Or, again, hacking the gg addition method:
thicken_lines <- function(size) {
structure(list(size = size), class = 'thickener')
}
` .gg` <- function(e1, e2) {
if(inherits(e2, 'thickener')) {
e1$layers <- lapply(e1$layers, function(x) {
x$aes_params <- c(x$aes_params, size = e2$size)
x
})
return(e1)
}
ggplot2:::` .gg`(e1, e2)
}
Which allows:
ggplot(mtcars, aes(gear, mpg))
geom_line(stat = 'summary', fun = mean)
thicken_lines(3)