I am wondering if it is somehow possible to access the columns of the provided data within a ggplot2
graph for the title. So something like that:
ggplot(mpg %>% filter(manufacturer == 'audi'),
aes(x = hwy, y = displ, label = model)) +
geom_point() +
geom_text(data = . %>% filter(hwy > 28)) +
ggtitle(unique(.$manufacurer))
I often create plots like in the example above to plot only subsets and would love to label automatically for the subset. At the moment, the .
will not be recognised within the ggtitle
but within geom_text
it is working.
EDIT:
Since I got a very nice comment and mark as duplicate from @Brian, is there maybe a solution to use this {}
trick within the dplyr::group_by
function? This is somehow not working. I would love to create individual plots for each group, but somehow only the complete data frame goes into the ggplot
call.
mpg %>%
group_by(manufacturer) %>% {
ggplot(., aes(cyl, displ, color=manufacturer)) +
geom_point() +
ggtitle(unique(.$manufacturer))
}
It says Audi but prints all manufacturers in the single plot.
To add a title to your plot, add the code +ggtitle("Your Title Here") to your line of basic ggplot code. Ensure you have quotation marks at the start and end of your title.
You add a chart title with the ggtitle() function.
To change the size of the title and subtitle, we add the theme() function to labs() or ggtitle() function, whatever you used. Here we use labs() function. Inside theme() function, we use plot. title parameter for doing changes in the title of plot and plot.
I would try the following as it is not possible to pipe outside aes()
.
ggplot(mpg %>% filter(manufacturer == 'audi'),
aes(x = hwy, y = displ, label = model)) +
geom_point() +
geom_text(data = . %>% filter(hwy > 28)) +
facet_wrap(~manufacturer)+
theme(strip.background = element_blank(),
strip.text = element_text(hjust = 0, size = 14))
The idea is to use a facet with empty strip background. If there are more names or variables one has to create an extra faceting variable using e.g. mutate(gr = "title")
mpg %>%
mutate(title="This is my plot") %>%
ggplot(aes(x = hwy, y = displ, col=manufacturer)) +
geom_point() +
facet_wrap(~title)+
theme(strip.background = element_blank(),
strip.text = element_text(hjust = 0, size = 14))
As you asked a second question here are two solutions for creating individual plots for each group
# first solution
p <- mpg %>%
group_by(manufacturer) %>%
do(plots= ggplot(., aes(cyl, displ)) +
geom_point() +
ggtitle(unique(.$manufacturer))
)
p %>% slice(1) %>% .$plots
# second solution
mpg %>%
nest(-manufacturer) %>%
mutate(plot = map2(data, manufacturer, ~ggplot(data=.x,aes(cyl, displ))+
geom_point() +
ggtitle(.y))) %>%
slice(1) %>% .$plot
Or save the data using
map2(paste0(p$manufacturer, ".pdf"), p$plots, ggsave)
Here's two ways I've done this using split
. You can use split
to split your dataframe into a named list of dataframes, based on a variable. So calling split(mpg, .$manufacturer)
gives you a list of dataframes, where each dataframe is associated with a manufacturer, e.g. split_df$audi
is the dataframe of all observations made by Audi.
library(dplyr)
library(purrr)
library(ggplot2)
split_df <- split(mpg, .$manufacturer)
First way you could do this is to just call ggplot
on a single item in the list. Since the list is named, names(split_df)[1]
will give you the name, "audi".
ggplot(split_df[[1]], aes(x = hwy, y = displ, label = model)) +
geom_point() +
geom_text(data = . %>% filter(hwy > 28)) +
ggtitle(names(split_df)[1])
That's kinda cumbersome, especially if you want plots for multiple manufacturers. When I've done this, I've used the map functions from purrr
. What's really cool is imap
, which maps over both the list and its names. Here I'm making a list of plots by mapping over the list of dataframes; each plot gets a title from the name of that list item.
plots <- imap(split_df, function(df, manufacturer) {
ggplot(df, aes(x = hwy, y = displ, label = model)) +
geom_point() +
geom_text(data = . %>% filter(hwy > 28)) +
ggtitle(manufacturer)
})
plots$audi
Then I can pull up a specific item from that list of plots. This is also handy for if you need to use walk
to map over them and save every plot or a subset of plots, or if you need to use a grid
function to arrange them into output, or really anything else cool that purrr
is great for.
Answering the follow-up about grouping by a variable to generate plots. I'm not sure how one would do this, nor what the output of a group_by(foo) %>% ggplot()
call would be (generate the plots one by one? store them? make a big plot of all of them stacked?).
One way you might try this is via lapply()
. Building on the solution you found to access the data from within the call:
library(dplyr)
library(ggplot2)
mfgs <- mpg %>% pull(manufacturer) %>% unique()
plot_list <- lapply(mfgs, function(mfg) {
mpg %>%
filter(manufacturer == mfg) %>% {
ggplot(., aes(cyl, displ, color=manufacturer)) +
geom_point() +
ggtitle(unique(.$manufacturer))
}
})
From there, you can access a given plot with plot_list[[i]]
, or (a) pass a named vector instead of mfgs
as defined, or just set the names of the list to the supplied vector of manufacturers, which lets you call plots by name:
names(plot_list) <- mfgs
plot_list[["nissan"]]
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With