By default, ggplot2 produces plots with a grey background. How do I change the color of the background of the plot?
For example, a plot produced by the following code:
library(ggplot2)
myplot<-ggplot(data=data.frame(a=c(1,2,3), b=c(2,3,4)), aes(x=a, y=b)) + geom_line()
myplot
To change the panel's background color, use the following code:
myplot + theme(panel.background = element_rect(fill = 'green', colour = 'red'))
To change the color of the plot (but not the color of the panel), you can do:
myplot + theme(plot.background = element_rect(fill = 'green', colour = 'red'))
See here for more theme details Quick reference sheet for legends, axes and themes.
To avoid deprecated opts and theme_rect use:
myplot + theme(panel.background = element_rect(fill='green', colour='red'))
To define your own custom theme, based on theme_gray but with some of your changes and a few added extras including control of gridline colour/size (more options available to play with at ggplot2.org):
theme_jack <- function (base_size = 12, base_family = "") {
theme_gray(base_size = base_size, base_family = base_family) %+replace%
theme(
axis.text = element_text(colour = "white"),
axis.title.x = element_text(colour = "pink", size=rel(3)),
axis.title.y = element_text(colour = "blue", angle=45),
panel.background = element_rect(fill="green"),
panel.grid.minor.y = element_line(size=3),
panel.grid.major = element_line(colour = "orange"),
plot.background = element_rect(fill="red")
)
}
To make your custom theme the default when ggplot is called in future, without masking:
theme_set(theme_jack())
If you want to change an element of the currently set theme:
theme_update(plot.background = element_rect(fill="pink"), axis.title.x = element_text(colour = "red"))
To store the current default theme as an object:
theme_pink <- theme_get()
Note that theme_pink is a list whereas theme_jack was a function. So to return the theme to theme_jack use theme_set(theme_jack()) whereas to return to theme_pink use theme_set(theme_pink).
You can replace theme_gray by theme_bw in the definition of theme_jack if you prefer. For your custom theme to resemble theme_bw but with all gridlines (x, y, major and minor) turned off:
theme_nogrid <- function (base_size = 12, base_family = "") {
theme_bw(base_size = base_size, base_family = base_family) %+replace%
theme(
panel.grid = element_blank()
)
}
Finally a more radical theme useful when plotting choropleths or other maps in ggplot, based on discussion here but updated to avoid deprecation. The aim here is to remove the gray background, and any other features that might distract from the map.
theme_map <- function (base_size = 12, base_family = "") {
theme_gray(base_size = base_size, base_family = base_family) %+replace%
theme(
axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.ticks.length=unit(0.3, "lines"),
axis.ticks.margin=unit(0.5, "lines"),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
legend.background=element_rect(fill="white", colour=NA),
legend.key=element_rect(colour="white"),
legend.key.size=unit(1.2, "lines"),
legend.position="right",
legend.text=element_text(size=rel(0.8)),
legend.title=element_text(size=rel(0.8), face="bold", hjust=0),
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
panel.margin=unit(0, "lines"),
plot.background=element_blank(),
plot.margin=unit(c(1, 1, 0.5, 0.5), "lines"),
plot.title=element_text(size=rel(1.2)),
strip.background=element_rect(fill="grey90", colour="grey50"),
strip.text.x=element_text(size=rel(0.8)),
strip.text.y=element_text(size=rel(0.8), angle=-90)
)
}
Here's a custom theme to make the ggplot2 background white and a bunch of other changes that's good for publications and posters. Just tack on +mytheme. If you want to add or change options by +theme after +mytheme, it will just replace those options from +mytheme.
library(ggplot2)
library(cowplot)
theme_set(theme_cowplot())
mytheme = list(
theme_classic()+
theme(panel.background = element_blank(),strip.background = element_rect(colour=NA, fill=NA),panel.border = element_rect(fill = NA, color = "black"),
legend.title = element_blank(),legend.position="bottom", strip.text = element_text(face="bold", size=9),
axis.text=element_text(face="bold"),axis.title = element_text(face="bold"),plot.title = element_text(face = "bold", hjust = 0.5,size=13))
)
ggplot(data=data.frame(a=c(1,2,3), b=c(2,3,4)), aes(x=a, y=b)) + mytheme + geom_line()
Related
I have many subsets of data that I would like to apply functions to and then plot. I have tailored my ggplot code to be what I'd like, aesthetically, and don't want to fill my notebook with these same long lists of specifications for every independent plot. Is it possible to take something like the following blocks of ggplot text, where
p = [some generic ggplot]
p = p + guides(colour = guide_legend(title = "year_collected", ncol = 2, keywidth = 1, keyheight = 1))
p = p + theme_minimal() +
theme(panel.grid.major = element_blank(),
axis.title.y=element_text(margin=margin(0,20,0,0)),
text=element_text(size=8, color="black",family="Arial"),
panel.grid.minor = element_blank(),
#axis.ticks = element_blank(),
legend.key.size = unit(.1, "in"),
legend.spacing.x = unit(.01,"in"),
legend.position = "bottom",
plot.title = element_text(hjust = 0.5))
p$layers <- p$layers[-1]
and use the R function options to capture all of these specifications and additions?
Thanks!
Alternatively, you can feed any lines of ggplot code into a list (with items comma separated) and add that:
my_theme_lines <- list(theme_minimal(),
theme(panel.grid.major = element_blank(),
axis.title.y=element_text(margin=margin(0,20,0,0)),
text=element_text(size=8, color="black",family="Arial"),
panel.grid.minor = element_blank(),
#axis.ticks = element_blank(),
legend.key.size = unit(.1, "in"),
legend.spacing.x = unit(.01,"in"),
legend.position = "bottom",
plot.title = element_text(hjust = 0.5)))
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
my_theme_lines
It's easy to define a custom ggplot theme, just use this template:
theme_custom <- function(){
#font <- "Georgia" # assign font family up front
theme_minimal() %+replace% #replace elements we want to change
# custom elements go here
theme(
)
}
Now with the question's settings.
theme_user3353556 <- function(){
font <- "Arial" # assign font family up front
theme_minimal() %+replace% #replace elements we want to change
# custom elements go here
theme(
panel.grid.major = element_blank(),
text = element_text(size = 8, color = "black"),
axis.title.y = element_text(margin = margin(0, 20, 0, 0)),
panel.grid.minor = element_blank(),
#axis.ticks = element_blank(),
legend.key.size = unit(0.1, "in"),
legend.spacing.x = unit(0.01,"in"),
legend.position = "bottom",
plot.title = element_text(hjust = 0.5)
)
}
ggplot(mtcars, aes(mpg, wt)) +
geom_point() +
theme_user3353556()
I am developing a custom theme based on the 538 theme in ggthemes. I have a particular use case where I would like to conditionally change the legend text if I am preparing graphs about organisms. I want to make the legend text italics if I am reporting Genus species results.
Here is my theme so far:
theme_EPI <- function() {
theme_fivethirtyeight(base_size = 14) %+replace%
theme(
panel.background = element_blank(),
plot.background = element_rect(fill = 'white', colour = NA),
plot.title = element_text(size = 18),
strip.text = element_text(size=14),
legend.text = element_text(size = 12, face = 'italic'),
legend.background = element_rect(fill="transparent", colour=NA),
legend.key = element_rect(fill="transparent", colour=NA),
panel.grid.major.y = element_line(colour = 'grey90'),
panel.grid.major.x = element_blank(),
strip.background = element_blank()
)
}
If have tried passing the parameter organism=TRUE to the the function call and then an ifelse(organism==TRUE, face='italic', 'face='plain') in the element_text.
Is this even possible in a custom theme?
Yes, this is definitely possible, you just have to slightly rethink how the ifelse() will work:
theme_EPI = function(organism = TRUE) {
theme_dark() %+replace%
# axis.title: labels for x and y axes
theme(axis.title = element_text(
face = ifelse(organism, 'italic', 'plain')
))
}
ggplot(iris, aes(Petal.Width, Petal.Length)) +
geom_point() +
theme_EPI() # Default: organism = TRUE
ggplot(iris, aes(Petal.Width, Petal.Length)) +
geom_point() +
theme_EPI(organism = FALSE)
I'm using the code below to try to create a PNG image that is only the image but there is still some text and a white border.
theplot <- data %>% ggplot(mapping = aes(x,y)) +
geom_point(mapping = aes(color=z), alpha = alpha, size = 0.75) +
scale_color_gradient(low="green", high="blue") +
theme_void() + theme(legend.position="none") + theme(axis.title = element_blank())
I've also tried the following.
theplot <- data %>% ggplot(mapping = aes(x,y)) +
geom_point(mapping = aes(color=z), alpha = alpha, size = 0.75) +
scale_color_gradient(low="green", high="blue") +
theme_void() + theme(axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
legend.position="none",
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
plot.background=element_blank())
I'm not very familiar with R so I'm not sure if ggplot is what I should be using to create just an image.
Is it ok like this ?
library(ggplot2)
library(ggthemes)
ggplot(mtcars, aes(mpg, wt)) + geom_point() +
theme(plot.margin=unit(c(0,0,0,0), unit="mm"))
+ theme_fivethirtyeight()
ggsave("myplot.png")
One can take a look at the code of theme_fivethirtyeight:
> theme_fivethirtyeight
function (base_size = 12, base_family = "sans")
{
(theme_foundation(base_size = base_size, base_family = base_family) +
theme(line = element_line(colour = "black"), rect = element_rect(fill = ggthemes_data$fivethirtyeight["ltgray"],
linetype = 0, colour = NA), text = element_text(colour = ggthemes_data$fivethirtyeight["dkgray"]),
axis.title = element_blank(), axis.text = element_text(),
axis.ticks = element_blank(), axis.line = element_blank(),
legend.background = element_rect(), legend.position = "bottom",
legend.direction = "horizontal", legend.box = "vertical",
panel.grid = element_line(colour = NULL), panel.grid.major = element_line(colour = ggthemes_data$fivethirtyeight["medgray"]),
panel.grid.minor = element_blank(), plot.title = element_text(hjust = 0,
size = rel(1.5), face = "bold"), plot.margin = unit(c(1,
1, 1, 1), "lines"), strip.background = element_rect()))
}
I must say I don't understand why that doesn't work with your custom theme. I don't see a major difference.
Using the data below, notice the legend does not properly describe geom_hline:
df<-data.frame(
points=c(.153,.144,.126,.035, .037, .039, .010,.015,.07),
days=gl(3,1,9,labels=c("Sun","Mon","Tues")),
lang=c("en","en","en","pt","pt","pt","ko","ko","ko"))
ggplot(data=df[df$lang=="en",])+
geom_point(aes(x=days,y=points),size=5,colour='cyan',show_guide=F)+
geom_point(aes(x=days,y=points,colour=days),size=4,show_guide=F)+
facet_wrap(~lang,ncol=1,scales="free")+
xlab("")+
ylab("")+
scale_y_continuous(labels = percent_format())+
theme(legend.position="right",
legend.title = element_blank(),
strip.text.x = element_text(size = 13, colour = 'black', angle = 0),
axis.text.x=element_text(angle=0, hjust=.5, vjust=0),
legend.position = 'none',
panel.background = element_rect(fill = "#545454"),
panel.grid.major = element_line(colour = "#757575"),
panel.grid.minor = element_line(colour = "#757575"))+
geom_hline(yintercept=.136,color='cyan',size=2, show_guide=T)
Is there some way to create a custom legend that describes the geom_hline? [I'd like the legend to to have the name "Legend" with only one value labled "avg"]
Searching so, I found an example: ggplot legend showing transparency and fill color. They used scale_fill_manual, which I tried, but could not improve the legend displayed above.
It's a bit awkward, but this seems to work:
hline <- data.frame(yint = 0.136,lt = 'Avg')
ggplot(data=df[df$lang=="en",])+
geom_point(aes(x=days,y=points),size=5,colour='cyan')+
geom_point(aes(x=days,y=points,colour=days),size=4)+
facet_wrap(~lang,ncol=1,scales="free")+
xlab("")+
ylab("")+
scale_y_continuous(labels = percent_format())+
theme(legend.position="right",
legend.title = element_blank(),
strip.text.x = element_text(size = 13, colour = 'black', angle = 0),
axis.text.x=element_text(angle=0, hjust=.5, vjust=0),
legend.position = 'none',
panel.background = element_rect(fill = "#545454"),
panel.grid.major = element_line(colour = "#757575"),
panel.grid.minor = element_line(colour = "#757575"))+
geom_hline(data = hline,aes(yintercept=yint,linetype = lt),color = "cyan",size=2,show_guide = TRUE) +
scale_colour_discrete(guide = "none") +
scale_linetype_manual(name = 'Legend',values = 1,guide = "legend")
Ah, but you've included legend.title = element_blank() in there, which is why the legend is not named. Remove that to include the name.
By default, ggplot2 produces plots with a grey background. How do I change the color of the background of the plot?
For example, a plot produced by the following code:
library(ggplot2)
myplot<-ggplot(data=data.frame(a=c(1,2,3), b=c(2,3,4)), aes(x=a, y=b)) + geom_line()
myplot
To change the panel's background color, use the following code:
myplot + theme(panel.background = element_rect(fill = 'green', colour = 'red'))
To change the color of the plot (but not the color of the panel), you can do:
myplot + theme(plot.background = element_rect(fill = 'green', colour = 'red'))
See here for more theme details Quick reference sheet for legends, axes and themes.
To avoid deprecated opts and theme_rect use:
myplot + theme(panel.background = element_rect(fill='green', colour='red'))
To define your own custom theme, based on theme_gray but with some of your changes and a few added extras including control of gridline colour/size (more options available to play with at ggplot2.org):
theme_jack <- function (base_size = 12, base_family = "") {
theme_gray(base_size = base_size, base_family = base_family) %+replace%
theme(
axis.text = element_text(colour = "white"),
axis.title.x = element_text(colour = "pink", size=rel(3)),
axis.title.y = element_text(colour = "blue", angle=45),
panel.background = element_rect(fill="green"),
panel.grid.minor.y = element_line(size=3),
panel.grid.major = element_line(colour = "orange"),
plot.background = element_rect(fill="red")
)
}
To make your custom theme the default when ggplot is called in future, without masking:
theme_set(theme_jack())
If you want to change an element of the currently set theme:
theme_update(plot.background = element_rect(fill="pink"), axis.title.x = element_text(colour = "red"))
To store the current default theme as an object:
theme_pink <- theme_get()
Note that theme_pink is a list whereas theme_jack was a function. So to return the theme to theme_jack use theme_set(theme_jack()) whereas to return to theme_pink use theme_set(theme_pink).
You can replace theme_gray by theme_bw in the definition of theme_jack if you prefer. For your custom theme to resemble theme_bw but with all gridlines (x, y, major and minor) turned off:
theme_nogrid <- function (base_size = 12, base_family = "") {
theme_bw(base_size = base_size, base_family = base_family) %+replace%
theme(
panel.grid = element_blank()
)
}
Finally a more radical theme useful when plotting choropleths or other maps in ggplot, based on discussion here but updated to avoid deprecation. The aim here is to remove the gray background, and any other features that might distract from the map.
theme_map <- function (base_size = 12, base_family = "") {
theme_gray(base_size = base_size, base_family = base_family) %+replace%
theme(
axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.ticks.length=unit(0.3, "lines"),
axis.ticks.margin=unit(0.5, "lines"),
axis.title.x=element_blank(),
axis.title.y=element_blank(),
legend.background=element_rect(fill="white", colour=NA),
legend.key=element_rect(colour="white"),
legend.key.size=unit(1.2, "lines"),
legend.position="right",
legend.text=element_text(size=rel(0.8)),
legend.title=element_text(size=rel(0.8), face="bold", hjust=0),
panel.background=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
panel.margin=unit(0, "lines"),
plot.background=element_blank(),
plot.margin=unit(c(1, 1, 0.5, 0.5), "lines"),
plot.title=element_text(size=rel(1.2)),
strip.background=element_rect(fill="grey90", colour="grey50"),
strip.text.x=element_text(size=rel(0.8)),
strip.text.y=element_text(size=rel(0.8), angle=-90)
)
}
Here's a custom theme to make the ggplot2 background white and a bunch of other changes that's good for publications and posters. Just tack on +mytheme. If you want to add or change options by +theme after +mytheme, it will just replace those options from +mytheme.
library(ggplot2)
library(cowplot)
theme_set(theme_cowplot())
mytheme = list(
theme_classic()+
theme(panel.background = element_blank(),strip.background = element_rect(colour=NA, fill=NA),panel.border = element_rect(fill = NA, color = "black"),
legend.title = element_blank(),legend.position="bottom", strip.text = element_text(face="bold", size=9),
axis.text=element_text(face="bold"),axis.title = element_text(face="bold"),plot.title = element_text(face = "bold", hjust = 0.5,size=13))
)
ggplot(data=data.frame(a=c(1,2,3), b=c(2,3,4)), aes(x=a, y=b)) + mytheme + geom_line()