Here is my code:
mtcars %>% filter(cyl == 4) %>%
ggplot(., aes(mpg, hp, color=hp)) +
geom_point() +
scale_color_gradient(low = "darkorange2", high = "darkred",
breaks=c(min(mtcars$hp), max(mtcars$hp)),
labels=c("Min","Max"))
What I would like to do is, include the breaks in the scale_color_gradient function in the filter I have called beforehand. I know that .$hp works in base R and only using the variable name in dplyr, but how do I use it in this case?
You can put all the plotting code in braces to keep the "right" object in the .. Also if you want to go from min to max, you can use range(). For example
mtcars %>% filter(cyl == 4) %>%
{ggplot(., aes(mpg, hp, color=hp)) +
geom_point() +
scale_color_gradient(low = "darkorange2", high = "darkred",
breaks=range(.$hp),
labels=c("Min","Max"))}
Related
I can do a scatterplot of two continuous variables like this:
mtcars %>%
ggplot(aes(x=mpg, y = disp)) + geom_point() +
geom_smooth(method="auto", se=TRUE, fullrange=FALSE, level=0.95)
I use cut to create 5 groups of mpg intervals for cars (any better command would do as well). I like to see the intervals in the graph, thus they are easy to understand.
mtcars %>%
mutate(mpg_groups = cut(mpg, 5)) %>%
group_by(mpg_groups) %>%
mutate(mean_disp = mean(disp)) %>%
ggplot(aes(x=mpg_groups, y = mean_disp)) + geom_point()
mpg_groups is a factor variable and can no longer be connected via geom_smooth().
# not working
mtcars %>%
mutate(mpg_groups = cut(mpg, 5)) %>%
group_by(mpg_groups) %>%
mutate(mean_disp = mean(disp)) %>%
ggplot(aes(x=mpg_groups, y = mean_disp)) + geom_point() +
geom_smooth(method="auto", se=TRUE, fullrange=FALSE, level=0.95)
What can I do with easy (tidyverse) code in order to create the mean values per group and connect them via line?
As a more or less general rule, when drawing a line via ggplot2 you have to explicitly set the group aesthetic in all cases where the variable mapped on x isn't a numeric, i.e. use e.g. group=1 to assign all observations to one group which I call 1 for simplicity:
library(ggplot2)
library(dplyr, warn=FALSE)
mtcars %>%
mutate(mpg_groups = cut(mpg, 5)) %>%
group_by(mpg_groups) %>%
mutate(mean_disp = mean(disp)) %>%
ggplot(aes(x = mpg_groups, y = mean_disp, group = 1)) +
geom_point() +
geom_smooth(method = "auto", se = TRUE, fullrange = FALSE, level = 0.95)
my question is basically a follow-up to this question. However, the problem is that in the said question the answer completely bypasses the fact that ggarrange is used and instead transfers the whole issue to be handled by the facets functionality of ggplot.
This doesn't work for me since I already am using facets in the sub-plots and I cannot use them again.
Here is some example code. I am wondering how to achieve that the two plots which are joined with ggarrange have the same range of y-axis (of course, not setting the limits manually).
mtcars %>%
group_split(vs) %>%
map(~ggplot(., aes(x = mpg, y = wt)) +
geom_point() +
facet_grid(rows = vars(am), cols = vars(gear))) %>%
ggarrange(plotlist = .)
As you can see, the left image's y-axis ranges from 2 to 5, while the right plot's y-axis ranges from 1.5 to 3.5. How can I make them be the same?
I'm once again arguing for abandoning the 'ggarrange' approach, this time in favour of the {patchwork} package, which allows you to apply an operation to all previous plots. In this case, we can use & scale_y_continuous(limits = ...) to set the limits for all plots.
library(ggplot2)
library(dplyr)
library(purrr)
library(patchwork)
mtcars %>%
group_split(vs) %>%
map(~ggplot(., aes(x = mpg, y = wt)) +
geom_point() +
facet_grid(rows = vars(am), cols = vars(gear))) %>%
wrap_plots() &
scale_y_continuous(limits = range(mtcars$wt))
Created on 2022-12-08 by the reprex package (v2.0.0)
One option would be to compute and add the range of your x and y variables to your dataset before splitting, which could then be used to set the limits.
library(dplyr)
library(ggplot2)
library(ggpubr)
library(purrr)
mtcars %>%
mutate(across(c(mpg, wt), list(range = ~list(range(.x))))) %>%
group_split(vs) %>%
map(~ggplot(., aes(x = mpg, y = wt)) +
geom_point() +
scale_x_continuous(limits = .$mpg_range[[1]]) +
scale_y_continuous(limits = .$wt_range[[1]]) +
facet_grid(rows = vars(am), cols = vars(gear))) %>%
ggarrange(plotlist = .)
I'm trying to plot the line graph for X=date Y=column which is XS1-XS10.
I use the lapply with a next function
plot_data_column = function (column) {
ggplot(data= excess_return, aes(y=column,x=date)) +
geom_line()+
geom_hline(yintercept = mean(excess_return$column), color="red")+
ggtitle(column)+
theme_minimal()
}
and then use lapply to plug in the columns of the dataset into the ggplot.
ggplots = lapply(excess_return[,1:10], plot_data_column)
My problem occurs with geom_hline which doesn't recognize the column and ggtitle(column).
P.s I have tried also like this
ggplots = lapply(colnames(excess_return[,1:10]), plot_data_column)
I wonder why R doesn't accept the XS1 as it were written manually by me?
because this code perfectly works.
ggplot(data= excess_return, aes(y=XS1,x=date)) +
geom_line()+
geom_hline(yintercept = mean(excess_return$XS1), color="red")+
theme_minimal()
The only thing what i want to is to iterate the XS1 to XS10.
Thank you for support
you can adapt this to your data strucutre:
plot_data_column = function (.data, .column) {
ggplot2::ggplot(data= .data, ggplot2::aes(y=!!dplyr::sym(.column),x = Petal.Width)) +
ggplot2::geom_line() +
ggplot2::geom_hline(yintercept = .data %>%
dplyr::pull(!!dplyr::sym(.column)) %>%
mean(),
color="red")+
ggplot2::ggtitle(.column) +
ggplot2::theme_minimal()
}
plots <- names(iris)[1:3] %>%
purrr::map(~plot_data_column(.data = iris, .column = .x))
You need to change the names(iris)[1:3] to your names names(excess_return)[1:10] and x = Petal.Width to x = date.
Another option:
library(tidyverse)
custom_ggplot_function <- function(var, var_name) {
ggplot(mtcars, aes(x = disp, y = var)) +
geom_line() +
geom_hline(yintercept = mean(var), color = "red") +
labs(y = var_name) +
ggtitle(var_name) +
theme_minimal()
}
mtcars %>%
select(mpg, cyl, disp) %>%
map2(.y = names(.), ~ custom_ggplot_function(.x, .y))
I am missing something crucial here and can't see it.
Why does min and max not work to set the axis limits?
mtcars %>%
select(mpg, cyl, disp, wt) %>%
filter(complete.cases(disp)) %>%
ggplot() +
geom_point(aes(x=mpg, y=disp, colour=cyl), size=3) +
xlim(min(mpg, na.rm=TRUE),max(mpg, na.rm=TRUE)) +
ylim(min(disp, na.rm=TRUE),max(disp, na.rm=TRUE)) +
scale_colour_gradient(low="red",high="green", name = "cyl")
This works:
mtcars %>%
select(mpg, cyl, disp, wt) %>%
filter(complete.cases(disp)) %>%
ggplot() +
geom_point(aes(x=mpg, y=disp, colour=cyl), size=3) +
# xlim(min(mpg, na.rm=TRUE),max(mpg, na.rm=TRUE)) +
# ylim(min(disp, na.rm=TRUE),max(disp, na.rm=TRUE)) +
scale_colour_gradient(low="red",high="green", name = "cyl")
ggplot cannot access the column values in the way that dplyr can.
You need to add in the data:
mtcars %>%
select(mpg, cyl, disp, wt) %>%
filter(complete.cases(disp)) %>%
ggplot() +
geom_point(aes(x=mpg, y=disp, colour=cyl), size=3) +
xlim(min(mtcars$mpg, na.rm=TRUE),max(mtcars$mpg, na.rm=TRUE)) +
ylim(min(mtcars$disp, na.rm=TRUE),max(mtcars$disp, na.rm=TRUE)) +
scale_colour_gradient(low="red",high="green", name = "cyl")
You can't reference column names in ggplot objects except inside aes() and in a formula or vars() in a facet_* function. But the helper function expand_scale is there to help you expand the scales in a more controlled way.
For example:
# add 1 unit to the x-scale in each direction
scale_x_continuous(expand = expand_scale(add = 1))
# have the scale exactly fit the data, no padding
scale_x_continuous(expand = expand_scale(0, 0))
# extend the scale by 10% in each direction
scale_x_continuous(expand = expand_scale(mult = .1))
See ?scale_x_continuous and especially ?expand_scale for details. It's also possible to selectively pad just the top or just the bottom of each scale, there are examples in ?expand_scale.
What's the easiest way to add titles to each ggplot that I've created below using the map function? I want the titles to reflect the name of each data frame - i.e. 4, 6, 8 (cylinders).
Thanks :)
mtcars_split <-
mtcars %>%
split(mtcars$cyl)
plots <-
mtcars_split %>%
map(~ ggplot(data=.,mapping = aes(y=mpg,x=wt)) +
geom_jitter()
# + ggtitle(....))
plots
Use map2 with names.
plots <- map2(
mtcars_split,
names(mtcars_split),
~ggplot(data = .x, mapping = aes(y = mpg, x = wt)) +
geom_jitter() +
ggtitle(.y)
)
Edit: alistaire pointed out this is the same as imap
plots <- imap(
mtcars_split,
~ggplot(data = .x, mapping = aes(y = mpg, x = wt)) +
geom_jitter() +
ggtitle(.y)
)
Perhaps you'd be interested in using facet_wrap instead
ggplot(mtcars, aes(y=mpg, x=wt)) + geom_jitter() + facet_wrap(~cyl)
You can use purrr::map2():
mtcars_split <- mtcars %>% split(mtcars$cyl)
plots <- map2(mtcars_split, titles,
~ ggplot(data=.x, aes(mpg,wt)) + geom_jitter() + ggtitle(.y)
)
EDIT
Sorry duplicated with Paul's answer.