how to overlay geom_rect and geom_boxplot in ggplot? - r

I am trying to use ggplot in order to overlay geom_rect under some boxplots.
I want the grey rectangle will be behind the box plots but I can't do it for some reason.
This is the code that I'm using:
ggplot(data, aes(x = reorder(genotype, -Shann.div, FUN = median), y = Shann.div)) +
geom_jitter(color="black", size=0.3, alpha=0.9) + geom_boxplot(outlier.shape = NA, coef = 0) +
geom_hline(yintercept = avg, color="red") +
#geom_hline(yintercept = (avg + 2 * SE), linetype='dashed', color="black") +
#geom_hline(yintercept = (avg - 2 * SE), linetype='dashed', color="black") +
geom_rect(aes(xmin=0, xmax=Inf, ymin=avg - SD, ymax=avg + SD), fill="grey", alpha=0.01) +
theme(panel.background = element_blank()) +
theme(axis.text.x=element_blank(), axis.ticks.x=element_blank()) +
ggtitle('Microbial UTO - Shannon diversity median') + xlab('genotype')

The ggplot package draws the geom layers in the order that you declare them. If you want the geom_rect layer in the back, put it before the other layers in the code:
ggplot(data, aes(x = reorder(genotype, -Shann.div, FUN = median), y = Shann.div)) +
geom_rect(aes(xmin=0, xmax=Inf, ymin=avg - SD, ymax=avg + SD), fill="grey", alpha=0.01) +
geom_jitter(color="black", size=0.3, alpha=0.9) + geom_boxplot(outlier.shape = NA, coef = 0) +
geom_hline(yintercept = avg, color="red") +
#geom_hline(yintercept = (avg + 2 * SE), linetype='dashed', color="black") +
#geom_hline(yintercept = (avg - 2 * SE), linetype='dashed', color="black") +
theme(panel.background = element_blank()) +
theme(axis.text.x=element_blank(), axis.ticks.x=element_blank()) +
ggtitle('Microbial UTO - Shannon diversity median') + xlab('genotype')

Related

coord_trans and coord_flip in same plot

I am trying to use both coord_trans and coord_flip in the same plot, but that seems to not work. Any suggestion how to use coord_trans for a plot that needs to be flipped?
Using scale_y_log10 does not work since it messes up the stat_summary
p <- ggplot(df.2,aes(reorder(x,y),y,colour=z)) +
geom_jitter(width = 0.2,size=0.1) +
theme_classic(base_size = 8) +
stat_summary(
fun = mean,
geom = "errorbar",
aes(ymax = ..y.., ymin = ..y..),
position = position_dodge(width = 0.1),
width = 0.7,
colour="black") +
coord_flip() +
theme(legend.position = "none") +
labs(x="",y="") +
scale_color_manual(values = mycolors)
p + coord_trans(y = "log10")

ggplot2 legend in 2 rows

I was unable to find a solution for putting ggplot2 legend in 2 rows.
Example
library(ggplot2)
theme_set(theme_bw())
data("midwest", package = "ggplot2")
ggplot(midwest, aes(x=area, y=poptotal)) +
geom_point(aes(col=state, size=popdensity)) +
geom_smooth(method="loess", se=F) +
xlim(c(0, 0.1)) +
ylim(c(0, 500000)) +
labs(y="Population",
x="Area",
title="") +
theme(legend.position = "top")
In the above image, I would like to have popdensity annotation on top (first row) and state annotation in the second row.
I think you're looking for theme(legend.box = "vertical") and guide_legend(order = ...)
library(ggplot2)
data("midwest", package = "ggplot2")
ggplot(midwest, aes(x=area, y=poptotal)) +
geom_point(aes(col=state, size=popdensity)) +
geom_smooth(method="loess", se=F) +
xlim(c(0, 0.1)) +
ylim(c(0, 500000)) +
labs(y="Population",
x="Area",
title="") +
theme_bw() +
theme(legend.position = "top",
legend.box = "vertical") +
guides(size = guide_legend(order = 1),
colour = guide_legend(order = 2))

Adjusting percentage decimals for a bar plot with facet_grid()

I have the following line:
p1 <- ggplot(mtcars, aes(x= cyl)) + geom_bar(aes(fill = vs), stat = "count") + geom_text(aes(label = scales::percent(..prop..), ymax= ..prop..), stat = "count", vjust = -0.5) + theme_classic() + ylab("Count") + facet_grid(vs ~ .) + ylim(0, 15)
which gives this plot. This is a plot where I want to keep the count integers on the y-axis, but I want the percentages displayed above each bar.
I would like to edit the number of decimals over each bar plot. However, when using the line below:
p2 <- ggplot(mtcars, aes(x= cyl)) + geom_bar(aes(fill = vs), stat = "count") + geom_text(aes(label = scales::percent(round((..count..)/sum(..count..),1)), ymax= ((..count..)/sum(..count..))), stat="count", vjust = -.25) + theme_classic() + ylab("Count") + facet_grid(vs ~ .) + ylim(0, 15)
The percentages are now off (see below), displaying the percentages for the whole plot, and not the separated facets. Is there a way to round the percentages without compromising the numbers?
You can use accuracy = 2 in the scales::percent function:
p1 <- ggplot(mtcars, aes(x= cyl)) + geom_bar(aes(fill = vs), stat = "count") +
geom_text(aes(label = scales::percent(..prop.., accuracy = 2), ymax= ..prop..), stat = "count", vjust = -0.5) +
theme_classic() + ylab("Count") + facet_grid(vs ~ .) + ylim(0, 15)
p1
There is an accuracy option in scales::percent:
p1 <- ggplot(mtcars, aes(x= cyl)) +
geom_bar(aes(fill = vs), stat = "count") +
geom_text(aes(label = scales::percent(..prop..,accuracy=2)),
stat = "count", vjust = -0.5) +
theme_classic() + ylab("Count") + facet_grid(vs ~ .) + ylim(0, 15)

grid.arrange + ggplot2 on Impulse Response Function (IRF)

I'm working in a Impulse-Response function plot (from a Vector AutoRegressive Model) with GGplot2 + grid.arrange. Below i give you my actual plot and the original one from the vars package. I really would like any hint to improve the final result
Would be nice, at least place both plots closer.
This is not a full question topic, but an improvement asking
here the full code
library(vars)
# Define lags
lag = VARselect(my_data, lag.max=12)
# Estimating var
my_var = VAR(my_data, min(lag$selection), type='both')
# Set the Impulse-Response data
impulse <- irf(my_var)
# Prepare plot data
number_ticks <- function(n) {function(limits) pretty(limits, n)}
lags <- c(1:11)
irf1<-data.frame(impulse$irf$PIB[,1],impulse$Lower$PIB[,1],
impulse$Upper$PIB[,1], lags)
irf2<-data.frame(impulse$irf$PIB[,2],impulse$Lower$PIB[,2],
impulse$Upper$PIB[,2])
# creating plots
PIB_PIB <- ggplot(data = irf1,aes(lags,impulse.irf.PIB...1.)) +
geom_line(aes(y = impulse.Upper.PIB...1.), colour = 'lightblue2') +
geom_line(aes(y = impulse.Lower.PIB...1.), colour = 'lightblue')+
geom_line(aes(y = impulse.irf.PIB...1.))+
geom_ribbon(aes(x=lags, ymax=impulse.Upper.PIB...1., ymin=impulse.Lower.PIB...1.), fill="lightblue", alpha=.1) +
xlab("") + ylab("PIB") + ggtitle("Orthogonal Impulse Response from PIB") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank()) +
geom_line(colour = 'black')
PIB_CON <- ggplot(data = irf2,aes(lags,impulse.irf.PIB...2.)) +
geom_line(aes(y = impulse.Upper.PIB...2.), colour = 'lightblue2') +
geom_line(aes(y = impulse.Lower.PIB...2.), colour = 'lightblue')+
geom_line(aes(y = impulse.irf.PIB...2.))+
geom_ribbon(aes(x=lags, ymax=impulse.Upper.PIB...2., ymin=impulse.Lower.PIB...2.), fill="lightblue", alpha=.1) +
scale_x_continuous(breaks=number_ticks(10)) +
xlab("") + ylab("CONSUMO") + ggtitle("") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank()) +
geom_line(colour = 'black')
# Generating plot
grid.arrange(PIB_PIB, PIB_CON, nrow=2)
Actual Output
Desired Style [when you call plot(irf(my_var))
Got something very close to desired model.
here the changed plots:
PIB_PIB <- ggplot(data = irf1,aes(lags,impulse.irf.PIB...1.)) +
geom_line(aes(y = impulse.Upper.PIB...1.), colour = 'lightblue2') +
geom_line(aes(y = impulse.Lower.PIB...1.), colour = 'lightblue')+
geom_line(aes(y = impulse.irf.PIB...1.))+
geom_ribbon(aes(x=lags, ymax=impulse.Upper.PIB...1., ymin=impulse.Lower.PIB...1.), fill="lightblue", alpha=.1) +
xlab("") + ylab("PIB") + ggtitle("Orthogonal Impulse Response from PIB") +
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
plot.margin = unit(c(2,10,2,10), "mm"))+
scale_x_continuous(breaks=number_ticks(10)) +
geom_line(colour = 'black')
PIB_CON <- ggplot(data = irf2,aes(lags,impulse.irf.PIB...2.)) +
geom_line(aes(y = impulse.Upper.PIB...2.), colour = 'lightblue2') +
geom_line(aes(y = impulse.Lower.PIB...2.), colour = 'lightblue')+
geom_line(aes(y = impulse.irf.PIB...2.))+
geom_ribbon(aes(x=lags, ymax=impulse.Upper.PIB...2., ymin=impulse.Lower.PIB...2.), fill="lightblue", alpha=.1) +
xlab("") + ylab("CONSUMO") + ggtitle("") +
theme(axis.title.x=element_blank(),
# axis.text.x=element_blank(),
# axis.ticks.x=element_blank(),
plot.margin = unit(c(-10,10,4,10), "mm"))+
scale_x_continuous(breaks=number_ticks(10)) +
geom_line(colour = 'black')
grid.arrange(PIB_PIB, PIB_CON, nrow=2)

Add confidence interval with labels to a bar plot

Given the following data:
df.plot <- data.frame(x=c("outcome name","outcome name"),
Condition=c("A","B"),
Score=c(41.5,51.8))
I can produce the following graph:
With this code:
ggplot(df.plot, aes(x=x, y=Score, fill=Condition)) +
geom_bar(position = 'dodge', stat='identity', width=.5) +
xlab(NULL) + coord_cartesian(ylim=c(0,100)) +
geom_text(aes(label=round(Score,2)), position=position_dodge(width=0.5), vjust=-0.25)
I would like to add a confidence interval to the "B" bar that goes from 27.5 to 76.1. I would like those values to be labeled in the graph.
I tried modifying df.plot to include this information and using geom_errorbar but i endup with 2 intervals intead of just one for Condition "B"
df.plot <- data.frame(x=c("outcome name","outcome name"),
Condition=c("A","B"),
Score=c(41.5,51.8),
lb = c(NULL,27.5),
ub = c(NULL,76.1))
ggplot(df.plot, aes(x=x, y=Score, fill=Condition)) +
geom_bar(position = 'dodge', stat='identity', width=.5) +
xlab(NULL) + coord_cartesian(ylim=c(0,100)) +
geom_errorbar(aes(ymin = lb, ymax = ub),
width = 0.2,
linetype = "dotted",
position = position_dodge(width = 0.5),
color="red", size=1) +
geom_text(aes(label=round(Score,2)), position=position_dodge(width=0.5), vjust=-0.25)
Finally, i'm not sure how to add the labels to the top and bottom of the interval.
NA is used for missing values not NULL
This should work as you expect:
df.plot <- data.frame(x=c("outcome name","outcome name"),
Condition=c("A","B"),
Score=c(41.5,51.8),
lb = c(NA,27.5),
ub = c(NA,76.1))
ggplot(df.plot, aes(x=x, y=Score, fill=Condition)) +
geom_bar(position = 'dodge', stat='identity', width=.5) +
xlab(NULL) + coord_cartesian(ylim=c(0,100)) +
geom_errorbar(aes(ymin = lb, ymax = ub),
width = 0.2,
linetype = "dotted",
position = position_dodge(width = 0.5),
color="red", size=1) +
geom_text(aes(label=round(Score,2)), position=position_dodge(width=0.5), vjust=-0.25) +
geom_text(aes(y = lb, label = lb), position=position_dodge(width=0.5), vjust=2)

Resources