Alirsd
Alirsd

Reputation: 113

How to create a customized theme similar to theme_bw in ggplot2?

I have the following codes in ggplot2:

require("ggplot2")
df <- data.frame(x=factor(rep(1:2,5)), y=rnorm(10))

ggplot(df , aes(x,y)) + geom_point(size = 3) + 
theme(axis.text.x = element_text(angle = 40, hjust = 1, colour = "black", size=12),
      plot.title = element_text(size=16, face="bold", hjust=0.5)) +
labs(title = "Plot")

Now, I want to change the background color to theme_bw, but then the main title and the x-axis options will be changed back to default.

ggplot(df , aes(x,y)) + geom_point(size = 3) + 
theme(axis.text.x = element_text(angle = 40, hjust = 1, colour = "black", size=12),
      plot.title = element_text(size=16, face="bold", hjust=0.5)) +
labs(title = "Plot") + 
theme_bw()

So, how can I change the theme to be the same as theme_bw but without losing other options?

Thanks

Upvotes: 6

Views: 3058

Answers (2)

Mike H.
Mike H.

Reputation: 14360

Another interesting option would be to write a function that only updates the theme if the the theme elements are not already defined. Thus it would be similar to +, but themes cannot be overwritten, only added:

`%+safe%` <- function(e1, e2){
  if (!is.theme(e1) || !is.theme(e2)) {
    stop("%+replace% requires two theme objects", call. = FALSE)
  }

  not_in_e1 <- names(e2)[!names(e2) %in% names(e1)]
  e1[not_in_e1] <- e2[not_in_e1]
  e1
}

ggplot(df , aes(x,y)) + geom_point(size = 3) + labs(title = "Plot") +
  theme(axis.text.x = element_text(angle = 40, hjust = 1, colour = "black", size=12),
        plot.title = element_text(size=16, face="bold", hjust=0.5))  %+safe% theme_bw()

Note, this needs to take two theme objects so you have to move labs() anyway.

Upvotes: 1

A Gore
A Gore

Reputation: 1900

Here's the solution (make sure that theme_bw() is used before the theme() that you want to apply:

ggplot(df , aes(x,y)) + geom_point(size = 3) + 
theme_bw() + 
theme(axis.text.x = element_text(angle = 40, hjust = 1, colour = "black", size=12),
      plot.title = element_text(size=16, face="bold", hjust=0.5)) +
labs(title = "Plot")

Upvotes: 9

Related Questions