I want to make a grupal frequency distribution plots and anotate the mean value. Most direct way is:
library(dplyr)
library(ggplot2)
load(mtcars)
mtcars0=mtcars%>%group_by(cyl)%>%mutate(MeanMpg=round(mean(mpg),2))
mtcars1=mtcars%>%group_by(cyl)%>%summarize(MeanMpg=round(mean(mpg),2))
p <- ggplot(mtcars0, aes(mpg, fill=cyl)) +
facet_wrap(. ~ cyl) +
geom_density(alpha=.2) +
geom_vline(data=mtcars1, aes(xintercept=MeanMpg), linetype="dashed", size=1) +
annotate("text", label = labels, size = 4, x = 15, y = 0.26)
p
the problem shows when i want to put mean values exactly on the middle of the mean line:
p <- ggplot(mtcars0, aes(mpg, fill=cyl)) +
facet_wrap(. ~ cyl) +
geom_density(alpha=.2) +
geom_vline(data=mtcars1, aes(xintercept=MeanMpg), linetype="dashed", size=1) +
annotate("text", label = labels, size = 4, x = mtcars1$MeanMpg, y = 0.26)
> p
Error: Aesthetics must be either length 1 or the same as the data (9): label
Ihn this case R multiply the text and i get an error.
How I can achive to put the label on each mean position in the facets?
You can use your mtcars1 data to specify the position of the labels:
ggplot(mtcars0, aes(mpg, fill=cyl)) +
facet_wrap(. ~ cyl) +
geom_density(alpha=.2) +
geom_vline(data = mtcars1, aes(xintercept = MeanMpg), linetype="dashed", size=1) +
geom_text(data = mtcars1, aes(x = MeanMpg, y = 0.25, label = MeanMpg))
Related
ggplot(data = results, aes(x = inst, y = value, group = inst)) +
geom_boxplot() +
facet_wrap(~color) +
#geom_line(data = mean,
#mapping = aes(x = inst, y = average, group = 1))
theme_bw()
When I run the code above with the code line commented, it runs and gives the graph below but I want a joining mean lines on the boxplots based on its own color category for each group in facet wraps. Any ideas how can I do that?
Your code is generally correct (though you'll want to add color = color to the aes() specification in geom_line()), so I suspect your mean dataset isn't set up correctly. Do you have means grouped by both your x axis and faceting variable? Using ggplot2::mpg as an example:
library(dplyr) # >= v1.1.0
library(ggplot2)
mean_dat <- summarize(mpg, average = mean(hwy), .by = c(cyl, drv))
ggplot(mpg, aes(factor(cyl), hwy)) +
geom_boxplot() +
geom_line(
data = mean_dat,
aes(y = average, group = 1, color = drv),
linewidth = 1.5,
show.legend = FALSE
) +
facet_wrap(~drv) +
theme_bw()
Alternatively, you could use stat = "summary" and not have to create a means dataframe at all:
ggplot(mpg, aes(factor(cyl), hwy)) +
geom_boxplot() +
geom_line(
aes(group = 1, color = drv),
stat = "summary",
linewidth = 1.5,
show.legend = FALSE
) +
facet_wrap(~drv) +
theme_bw()
# same result as above
My current legend displays the shapes of the points in the chart, crossed out by the line. Id like to remove this line in the legend and just display the shapes.
The code looks like this:
p <- ggplot(data=cumdf, aes(x=quarters2)) +
geom_line(aes(y = mean_cumsum, colour='Platform participants'), size = 1.5)+
geom_point(aes(y = mean_cumsum, colour='Platform participants', shape='Platform participants'), size=3) +
geom_line(aes(y = mean_interventions, colour='Actions'), size=1.5) +
geom_point(aes(y = mean_interventions, colour='Actions', shape='Actions'), size=3) +
geom_line(aes(y = mean_sales, colour="Adopters"), size=1.5) +
geom_point(aes(y = mean_sales, colour='Adopters', shape='Adopters'), size=3) +
xlab("Quarters") +
ylab("Cumulative occurences") +
scale_shape_manual("", values=c("Platform participants" = 16, "Actions" = 17, "Adopters"=15)) +
scale_colour_manual("",breaks = c("Platform participants", "Actions", "Adopters"),
values = c ("#C80000", "#696969", "#4E33FF")) +
theme_stata(base_size = 15, base_family = "sans", scheme = "s2color") +
scale_x_continuous(n.breaks=14) +
geom_vline(xintercept=3, linetype='dashed', size=1.7)
p
Add show.legend to your geom_line. Since you have multiple calls to geom_line, you need to add it to all of them.
I'll demonstrate using mtcars, updated for a factor.
dat <- transform(mtcars, cyl = factor(cyl))
Before the change:
ggplot(dat, aes(mpg, disp, group = cyl, color = cyl, shape = cyl)) +
geom_line() +
geom_point()
Add show.legend=FALSE:
ggplot(dat, aes(mpg, disp, group = cyl, color = cyl, shape = cyl)) +
geom_line(show.legend = FALSE) +
geom_point()
The answer was found in the comments, by adding show.legend=FALSE to geom.line() .
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")
I am using facet_grid() to plot multiple plot divided per groups of data. For each plot, I want to add in the corner the highest value of the Y axis. I've tried several hacks but it never gives me the expected results. This answer partially helps me but the value I want to add will constantly be changing, therefore I don't see how I can apply it.
Here is a minimal example, I'd like to add the red numbers on the graph below:
library(ggplot2)
data <- data.frame('group'=rep(c('A','B'),each=4),'hour'=rep(c(1,2,3,4),2),'value'=c(5,4,2,3,6,7,4,5))
ggplot(data,aes(x = hour, y = value)) +
geom_line() +
geom_point() +
theme(aspect.ratio=1) +
scale_x_continuous(name ="hours", limits=c(1,4)) +
scale_y_continuous(limits=c(1,10),breaks = seq(1, 10, by = 2))+
facet_grid( ~ group)
Thanks for your help!
library(dplyr)
data2 <- data %>% group_by(group) %>% summarise(Max = max(value))
ggplot(data,aes(x = hour, y = value)) +
geom_line() +
geom_point() +
geom_text(aes(label = Max), x = Inf, y = Inf, data2,
hjust = 2, vjust = 2, col = 'red') +
theme(aspect.ratio=1) +
scale_x_continuous(name ="hours", limits=c(1,4)) +
scale_y_continuous(limits=c(1,10),breaks = seq(1, 10, by = 2))+
facet_grid( ~ group)
This does the trick. If you always have fixed ranges you can position the text manually.
library(ggplot2)
data <- data.frame('group'=rep(c('A','B'),each=4),'hour'=rep(c(1,2,3,4),2),'value'=c(5,4,2,3,6,7,4,5))
ggplot(data,aes(x = hour, y = value)) +
geom_line() +
geom_point() +
geom_text(
aes(x, y, label=lab),
data = data.frame(
x=Inf,
y=Inf,
lab=tapply(data$value, data$group, max),
group=unique(data$group)
),
vjust="inward",
hjust = "inward"
) +
theme(aspect.ratio=1) +
scale_x_continuous(name ="hours", limits=c(1,4)) +
scale_y_continuous(limits=c(1,10),breaks = seq(1, 10, by = 2))+
facet_grid( ~ group)
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