Combined bar plot and points in ggplot2 - r

I would like to plot a "combined" bar plot with points.
Consider to following dummy data:
library(ggplot2)
library(gridExtra)
library(dplyr)
se <- function(x){sd(x)/sqrt(length(x))}
p1 <- ggplot(mtcars, aes(y=disp, x=cyl, fill=cyl))
p1 <- p1 + geom_point() + theme_classic() + ylim(c(0,500))
my_dat <- summarise(group_by(mtcars, cyl), my_mean=mean(disp),my_se=se(disp))
p2 <- ggplot(my_dat, aes(y=my_mean,x=cyl,ymin=my_mean-my_se,ymax=my_mean+my_se))
p2 <- p2 + geom_bar(stat="identity",width=0.75) + geom_errorbar(stat="identity",width=0.75) + theme_classic() + ylim(c(0,500))
The final plot should look like that:

You can add layers together, but if they have different data and/or aesthetics you'll want to include the data and aes arguments in each graphical layer.
p3 <- ggplot() +
geom_bar(data=my_dat, aes(y=my_mean,x=cyl,ymin=my_mean-my_se,ymax=my_mean+my_se), stat="identity", width = 0.75) +
geom_errorbar(data=my_dat, aes(y=my_mean,x=cyl,ymin=my_mean-my_se,ymax=my_mean+my_se), width = 0.75) +
geom_point(data=mtcars, aes(y=disp, x=cyl, fill=cyl)) +
ylim(c(0,500)) +
theme_classic()
If you want to make it so that the the points are off to the side of the bars, you could subtract an offset from the cyl values to move over the points. Like #LukeA mentioned, by changing the geom_point to geom_point(data=mtcars, aes(y=disp, x=cyl-.5, fill=cyl)).

You can specify each layer individually to ggplot2. Often you are using the same data frame and options for each geom, so it makes sense to set defaults in ggplot(). In your case you should specify each geom separately:
library(ggplot2)
library(gridExtra)
library(dplyr)
se <- function(x){sd(x)/sqrt(length(x))}
my_dat <- summarise(group_by(mtcars, cyl),
my_mean = mean(disp),
my_se = se(disp))
p1 <- ggplot() +
geom_bar(data = my_dat,
aes(y = my_mean, x = cyl,
ymin = my_mean - my_se,
ymax = my_mean + my_se), stat="identity", width=0.75) +
geom_errorbar(data = my_dat,
aes(y = my_mean, x = cyl,
ymin = my_mean - my_se,
ymax = my_mean + my_se), stat="identity", width=0.75) +
geom_point(data = mtcars, aes(y = disp, x = cyl, fill = cyl)) +
theme_classic() + ylim(c(0,500))
p1

Related

ggplot2 and grid.arrange, place legend below arranged plots

I am facing a problem when I arrange 2 ggplots next to each other using grid.arrange().
I want to place a legend evenly below both plots.
So I have (pseudocode):
p1 <- ggplot(data = df, aes(group = name, color=as.factor(fac), y = ys, x= (xs))) +
geom_point() +
geom_line() +
theme(legend.position="bottom")
p2 <- ggplot(data = df, aes(group = name, color=as.factor(fac), y = ys, x= (xs))) +
geom_point() +
geom_line() +
grid.arrange(p1,p2, ncol=2, widths=c(0.9,1))
Is there any possibility to arrange the legend so that it is positioned evenly below both plots? If I do it as above, the legend is (logically) placed below the first plot.
With package patchwork you could try this...
library(ggplot2)
library(patchwork)
p1 <- ggplot(data = mtcars, aes(group = gear, color=as.factor(am), y = mpg, x = hp)) +
geom_point() +
geom_line()
p2 <- ggplot(data = mtcars, aes(group = gear, color=as.factor(am), y = mpg, x = hp)) +
geom_point() +
geom_line()
p1 + p2 +
plot_layout(guides = "collect") &
theme(legend.position='bottom')
Created on 2022-02-04 by the reprex package (v2.0.1)

apply transparent background to divide plot area based on x values using ggplot

I would appreciate any help to apply the transparent background colours below to
divide into two parts the plot area based on x-values as illustrated in the plot below (vertical division).
Here are my sample data and code:
mtcars$cyl <- as.factor(mtcars$cyl)
ggplot(mtcars, aes(x=wt, y=mpg, color=cyl)) +
geom_point() +
theme(legend.position="none")+
geom_smooth(method=lm, se=FALSE, fullrange=TRUE)
Here is the plot I would like to replicate, and the legend illustrates the change I want to implement:
Thank you in advance.
I think you want something like this. You'll have to designate groups and fill by that group in your geom_ribbon, and set your ymin and ymax as you like.
library(tidyverse)
mtcars$group <- ifelse(mtcars$wt <= 3.5, "<= 3.5", "> 3.5")
mtcars <- arrange(mtcars, wt)
mtcars$group2 <- rleid(mtcars$group)
mtcars_plot <- head(do.call(rbind, by(mtcars, mtcars$group2, rbind, NA)), -1)
mtcars_plot[,c("group2","group")] <- lapply(mtcars_plot[,c("group2","group")], na.locf)
mtcars_plot[] <- lapply(mtcars_plot, na.locf, fromLast = TRUE)
ggplot(mtcars_plot, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(aes(), method=lm, se=F, fullrange=TRUE) +
geom_ribbon(aes(ymin = mpg *.75, ymax = mpg * 1.25, fill = group), alpha = .25) +
labs(fill = "Weight Class")
Edit:
To map confidence intervals using geom_ribbon you'll have to calculate them beforehand using lm and predict.
mtmodel <- lm(mpg ~ wt, data = mtcars)
mtcars$Low <- predict(mtmodel, newdata = mtcars, interval = "confidence")[,2]
mtcars$High <- predict(mtmodel, newdata = mtcars, interval = "confidence")[,3]
Followed by the previous code to modify mtcars. Then plot with the calculated bounds.
ggplot(mtcars_plot, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(aes(), method=lm, se=F, fullrange=TRUE) +
geom_ribbon(aes(ymin = Low, ymax = High, fill = group), alpha = .25) +
labs(fill = "Weight Class") +
scale_fill_manual(values = c("red", "orange"), name = "fill")

Adding smoother to ggplot 2

I have used the following code to create a plot in r using ggplot2:
g <- ggplot(newdata, aes(MVPAper, FMI) +
geom_smooth(method = 'lm'))
I then added the following:
p <- g + geom_point(aes(color = Age)) +
facet_grid(Age ~ .) +
stat_smooth(method = 'lm') +
theme_bw(base_family = 'Times')`
I am wanting to have a smoother for each of the four graphs I have created, using the facet grid to split the graph into four ages 8,9,12,and 15) can anyone assist with my code?
You don't need both geom_smooth() and stat_smooth(). Try this:
library(tidyverse)
df <- diamonds %>% filter(price < 10000, carat < 2.5)
g <- ggplot(df, aes(carat, price, color = cut))
g +
geom_point() +
geom_smooth(method = 'lm') +
facet_grid(cut ~ .) +
theme_bw()

Plot mean in an R plot

I would like to add a mean of valuus to windows in a scatter plot I have. I created the scatter plot with ggplot2
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point()
This will give the scatter plot but I woudl like to add add the mean of a window (say size equals 1) and plot this points of the mean as a line. Additionally I woudl like to have vertical bars at each point to indicate the variance.
Mtcars is the data set standard available in ggplot 2
This uses the new dplyr library.
library(dplyr)
forLines <- mtcars %.%
group_by(cut(wt, breaks = 6)) %.%
summarise(mean_mpg = mean(mpg), mean_wt = mean(wt))
p +
geom_point(size=5) +
geom_boxplot(aes(group = cut(wt, breaks = 6))) +
geom_line(data=forLines,aes(x=mean_wt,y=mean_mpg))
Maybe this is what you're looking for:
library(ggplot2)
s <- seq(0, ceiling(max(mtcars$wt)), 1)
ind <- as.integer(cut(mtcars$wt, s))
myfun <- function(i)
c(y = mean(i), ymin = mean(i) - var(i), ymax = mean(i) + var(i))
ggplot(mtcars, aes(wt, mpg)) +
geom_point() +
stat_summary(fun.data = myfun, aes(group = ind, x = ind - .5),
colour = "red") +
stat_summary(fun.y = mean, aes(x = ind - .5), geom = "line",
colour = "red")
Is this what you want?
p <- ggplot(mtcars, aes(wt, mpg))
p + geom_point() + geom_smooth(aes(wt, mpg, group=1), method = "lm")

Drawing only boundaries of stat_smooth in ggplot2

When using stat_smooth() with geom_point is there a way to remove the shaded fit region, but only draw its outer bounds? I know I can remove the shaded region with something like:
geom_point(aes(x=x, y=y)) + geom_stat(aes(x=x, y=y), alpha=0)
but how can I make the outer bounds of it (outer curves) still visible as faint black lines?
You can also use geom_ribbon with fill = NA.
gg <- ggplot(mtcars, aes(qsec, wt))+
geom_point() +
stat_smooth( alpha=0,method='loess')
rib_data <- ggplot_build(gg)$data[[2]]
ggplot(mtcars)+
stat_smooth(aes(qsec, wt), alpha=0,method='loess')+
geom_point(aes(qsec, wt)) +
geom_ribbon(data=rib_data,aes(x=x,ymin=ymin,ymax=ymax,col='blue'),
fill=NA,linetype=1)
...and if for some reason you don't want the vertical bars, you can just use two geom_line layers:
ggplot(mtcars)+
stat_smooth(aes(qsec, wt), alpha=0,method='loess')+
geom_point(aes(qsec, wt)) +
geom_line(data = rib_data,aes(x = x,y = ymax)) +
geom_line(data = rib_data,aes(x = x,y = ymin))
There are most likely easier ways, but you may try this as a start. I grab data for the confidence interval with ggbuild, which I then use in geom_line
# create a ggplot object with a linear smoother and a CI
library(ggplot2)
gg <- ggplot(data = mtcars, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(method = "lm")
gg
# grab the data from the plot object
gg_data <- ggplot_build(gg)
str(gg_data)
head(gg_data$data[[2]])
gg2 <- gg_data$data[[2]]
# plot with 'CI-lines' and the shaded confidence area
ggplot(data = mtcars, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(method = "lm", se = TRUE, size = 1) +
geom_line(data = gg2, aes(x = x, y = ymin), size = 0.02) +
geom_line(data = gg2, aes(x = x, y = ymax), size = 0.02)
# plot with 'CI-lines' but without confidence area
ggplot(data = mtcars, aes(x = wt, y = mpg)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE, size = 1) +
geom_line(data = gg2, aes(x = x, y = ymin), size = 0.02) +
geom_line(data = gg2, aes(x = x, y = ymax), size = 0.02)

Resources