Can ggplot theme formatting be saved as an object?
You can make a theme object without any problems, e.g:
mytheme<-theme(panel.background=element_rect(colour="green"))
It is even easier, if this is your standard theme to type
old_theme<- theme_update(panel.background=element_rect(colour="green"))
In the former case you write:
ggplot(...)+mytheme
while in the latter, because your custom theme is now the standard theme, it is only necessary to type:
ggplot(...)
Error: Don't know how to add RHS to a theme object when saving theme formatting in R
Hi welcome to stackoverflow. You cannot change labels within the theme call, nor can you save a theme with labels that's why you get that error. This happens because labs() is not a theme. Before saving the theme, ggplot checks if the theme is a theme and returns that error if it isn't.
is.theme(labs(caption="Graphics: XYZ\nSource: ABC"))
[1] FALSE
Save the theme and then add the labels separately.
my_theme <- theme(plot.caption=element_text(size=20, vjust = 0.55,
hjust = 0.99, colour = "black", family = "Eurostile"),
plot.background = element_rect(fill = "#DCDCDC"),
panel.background = element_rect(colour = "#DCDCDC"),
axis.text = element_text(colour = "black", size = 20))
# assuming you plot is saved as p
p + my_theme + labs(caption="Graphics: XYZ\nSource: ABC")
That saves the theme and then you can add the labels to your plot when you add the theme. You can also save labels to the plot object p with the calls to ggplot and geom etc.
Store custom ggplot styles in object
You can create a list of customizations and then apply that to each plot. For example:
customPlot = list(
theme(plot.margin = unit(c(1,1,2,2), "cm"),
axis.text.x = element_text(vjust=0.5, size=20),
plot.title=element_text(size=20, vjust=2),
panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
axis.title.x = element_blank(), axis.title.y = element_blank(),
panel.background = element_rect(fill = "#D9D9D9")),
coord_cartesian(ylim = c(0, 1)),
scale_fill_manual(values=c("#05f2ae", "#17b0c4"))
)
ggplot(mdf, aes (x=group, y=value, fill = variable)) +
geom_bar(stat="identity", position="dodge", alpha = 0.8) +
geom_bar(stat="identity", position="dodge", color = "#A9A9A9", alpha = 0.8) +
geom_text(aes(x=group, y=value, ymax=value, label=value),
position=position_dodge(1), vjust=-1, size=12) +
customPlot
GGPlot2 Preset - Creating a function with certain ggplot2 aesthetics options
You can store things to be added to a plot in a list. You can then re-use this list by adding it to a plot.
library(ggplot2)
library(ggthemes)
library(magrittr)
common_options <- list(
scale_fill_viridis_d(name = "", option = "inferno", begin = 0.3, end = 0.7, direction = -1),
scale_shape_tableau(),
theme_economist(),
theme(plot.background = element_rect(fill = "white"),
plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
plot.margin = unit(c(1,1,1,1), "cm"))
)
df1 <- data.frame(name = c("name1","name2","name3","name4"),
variable = c("var1","var1","var2","var2"),
value = c(15,16,17,18))
df1 %>%
ggplot(aes(x = name, y = value, fill = variable)) +
geom_bar(stat = "identity", position = position_stack()) +
labs(title = "Plot Title",
subtitle = "month 1",
x="",
y="Count") +
common_options
Created on 2021-07-20 by the reprex package (v1.0.0)
can you pre-compose ggplot elements for repeated use?
Following this answer, you can put all these into a list and then add it via +
to your plot. This list can include theme
elements.
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)) )
Here's what it could look like in practice.
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
Conditionally modify ggplot theme based on presence of facets?
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.
Related Topics
Geom_Col Is Assigning the Wrong Independent Variable
Meaning of Objects Being Masked by the Global Environment
Using a Static (Prebuilt) PDF Vignette in R Package
Glpk: No Such File or Directory Error When Trying to Install R Package
Scaling a Numeric Matrix in R with Values 0 to 1
Calculate Mean Across Rows with Na Values in R
Fastest Way to Read in 100,000 .Dat.Gz Files
Can Ggplot Theme Formatting Be Saved as an Object
Plots with Good Resolution for Printing and Screen Display
Create Sections Through a Loop with Knitr
How Can R Loop Over Data Frames
R Library for Discrete Markov Chain Simulation
Join Data.Table on Exact Date or If Not the Case on the Nearest Less Than Date
Caching the Mean of a Vector in R
What's the Difference in Using a Semicolon or Explicit New Line in R Code