How to annotate geom_bar above bars? - r

I'm trying to do a simple plot using ggplot2:
library(ggplot2)
ggplot(diamonds, aes(x = cut, y = depth)) +
geom_bar(stat = "identity", color = "blue") +
facet_wrap(~ color) +
geom_text(aes(x = cut, y = depth, label = cut, vjust = 0))
How can I annotate this plot so that I get annotations above bars? Now geom_text puts labels at the bottom of the bars, but I want them above these bars.

You can use stat_summary() to calculate position of y values as sum of depth and use geom="text" to add labels. The sum is used because your bars shows the sum of depth values for each cut value.
As suggest by #joran it is better to use stat_summary() instead of geom_bar() to show sums of y values because stat="identity" makes problems due to overplotting of bars and if there will be negative values then bar will start in negative part of plot and end in positive part - result will be not the actual sum of values.
ggplot(diamonds[1:100,], aes(x = cut, y = depth)) +
facet_wrap(~ color) +
stat_summary(fun.y = sum, geom="bar", fill = "blue", aes(label=cut, vjust = 0)) +
stat_summary(fun.y = sum, geom="text", aes(label=cut), vjust = 0)
You can also precalculate sum of depth values and the you can use geom_bar() with stat="identity" and geom_text().
library(plyr)
diamonds2<-ddply(diamonds,.(cut,color),summarise,depth=sum(depth))
ggplot(diamonds2,aes(x=cut,y=depth))+
geom_bar(stat="identity",fill="blue")+
geom_text(aes(label=cut),vjust=0,angle=45,hjust=0)+
facet_wrap(~color)

Related

ggplot2 - using two different color scales for same fill in overlayed plots

A very similar question to the one asked here. However, in that situation the fill parameter for the two plots are different. For my situation the fill parameter is the same for both plots, but I want different color schemes.
I would like to manually change the color in the boxplots and the scatter plots (for example making the boxes white and the points colored).
Example:
require(dplyr)
require(ggplot2)
n<-4*3*10
myvalues<- rexp((n))
days <- ntile(rexp(n),4)
doses <- ntile(rexp(n), 3)
test <- data.frame(values =myvalues,
day = factor(days, levels = unique(days)),
dose = factor(doses, levels = unique(doses)))
p<- ggplot(data = test, aes(x = day, y = values)) +
geom_boxplot( aes(fill = dose))+
geom_point( aes(fill = dose), alpha = 0.4,
position = position_jitterdodge())
produces a plot like this:
Using 'scale_fill_manual()' overwrites the aesthetic on both the boxplot and the scatterplot.
I have found a hack by adding 'colour' to geom_point and then when I use scale_fill_manual() the scatter point colors are not changed:
p<- ggplot(data = test, aes(x = day, y = values)) +
geom_boxplot(aes(fill = dose), outlier.shape = NA)+
geom_point(aes(fill = dose, colour = factor(test$dose)),
position = position_jitterdodge(jitter.width = 0.1))+
scale_fill_manual(values = c('white', 'white', 'white'))
Are there more efficient ways of getting the same result?
You can use group to set the different boxplots. No need to set the fill and then overwrite it:
ggplot(data = test, aes(x = day, y = values)) +
geom_boxplot(aes(group = interaction(day, dose)), outlier.shape = NA)+
geom_point(aes(fill = dose, colour = dose),
position = position_jitterdodge(jitter.width = 0.1))
And you should never use data$column inside aes - just use the bare column. Using data$column will work in simple cases, but will break whenever there are stat layers or facets.

ggplot2 coord_flip() with geom_text

I'm trying to find a way to easily flip a plot annotated with geom_text(). The problem is that if I use coord_flip(), the labels are kind of not flipped.
A simple example, if I flip the plot like that:
df <- count(diamonds, cut)
ggplot(df, aes(x = cut, y = n, label = n)) +
geom_bar(stat = "identity") +
geom_text()
by adding coord_flip(), I'm getting:
I know that this could be a desired behaviour in some cases but instead of that, I need the labels on the bars to stay aligned with the bars and look more like:
Is there any solution to that?
You can use the angle aesthetic in geom_text, setting it to a fixed value.
ggplot(df, aes(x = cut, y = n, label = n)) +
geom_bar(stat = "identity") +
geom_text(angle = 270) +
coord_flip()

R ggplot2: Add means as horizontal line in a boxplot

I have created a boxplot using ggplot2:
library(ggplot2)
dat <- data.frame(study = c(rep('a',50),rep('b',50)),
FPKM = c(rnorm(1:50),rnorm(1:50)))
ggplot(dat, aes(x = study, y = FPKM)) + geom_boxplot()
The boxplot shows the median as a horizontal line across each box.
How do I add a dashed line to the box representing the mean of that group?
Thanks!
You can add horizontal lines to plots by using stat_summary with geom_errorbar. The line is horizontal because the y minimum and maximum are set to be the same as y.
ggplot(dat, aes(x = study, y = FPKM)) +
geom_boxplot() +
stat_summary(fun.y = mean, geom = "errorbar", aes(ymax = ..y.., ymin = ..y..),
width = .75, linetype = "dashed")

geom_histogram and data labels [duplicate]

Below code works well and it labels the barplot correctly, However, if I try geom_text for a histogram I fail since geom_text requires a y-component and a histogram's y component is not part of the original data.
Label an "ordinary" bar plot (geom_bar(stat = "identity") works well:
ggplot(csub, aes(x = Year, y = Anomaly10y, fill = pos)) +
geom_bar(stat = "identity", position = "identity") +
geom_text(aes(label = Anomaly10y,vjust=1.5))
My Problem: How to get the correct y and label (indicated by ?) for geom_text, to put labels on top of the histogram bars
ggplot(csub,aes(x = Anomaly10y)) +
geom_histogram()
geom_text(aes(label = ?, vjust = 1.5))
geom_text requires x, y and labels. However, y and labels are not in the original data, but generated by the geom_histogram function. How can I extract the necessary data to position labels on a histogram?
geom_histogram() is just a fancy wrapper to stat_bin so you can all that yourself with the bars and text that you like. Here's an example
#sample data
set.seed(15)
csub<-data.frame(Anomaly10y = rpois(50,5))
And then we plot it with
ggplot(csub,aes(x=Anomaly10y)) +
stat_bin(binwidth=1) + ylim(c(0, 12)) +
stat_bin(binwidth=1, geom="text", aes(label=..count..), vjust=-1.5)
to get
Ok to make it aesthetically appealing here is the solution:
set.seed(15)
csub <- data.frame(Anomaly10y = rpois(50, 5))
Now Plot it
csub %>%
ggplot(aes(Anomaly10y)) +
geom_histogram(binwidth=1) +
stat_bin(binwidth=1, geom='text', color='white', aes(label=..count..),
position=position_stack(vjust = 0.5))
resultant plot will be

Get values and positions to label a ggplot histogram

Below code works well and it labels the barplot correctly, However, if I try geom_text for a histogram I fail since geom_text requires a y-component and a histogram's y component is not part of the original data.
Label an "ordinary" bar plot (geom_bar(stat = "identity") works well:
ggplot(csub, aes(x = Year, y = Anomaly10y, fill = pos)) +
geom_bar(stat = "identity", position = "identity") +
geom_text(aes(label = Anomaly10y,vjust=1.5))
My Problem: How to get the correct y and label (indicated by ?) for geom_text, to put labels on top of the histogram bars
ggplot(csub,aes(x = Anomaly10y)) +
geom_histogram()
geom_text(aes(label = ?, vjust = 1.5))
geom_text requires x, y and labels. However, y and labels are not in the original data, but generated by the geom_histogram function. How can I extract the necessary data to position labels on a histogram?
geom_histogram() is just a fancy wrapper to stat_bin so you can all that yourself with the bars and text that you like. Here's an example
#sample data
set.seed(15)
csub<-data.frame(Anomaly10y = rpois(50,5))
And then we plot it with
ggplot(csub,aes(x=Anomaly10y)) +
stat_bin(binwidth=1) + ylim(c(0, 12)) +
stat_bin(binwidth=1, geom="text", aes(label=..count..), vjust=-1.5)
to get
Ok to make it aesthetically appealing here is the solution:
set.seed(15)
csub <- data.frame(Anomaly10y = rpois(50, 5))
Now Plot it
csub %>%
ggplot(aes(Anomaly10y)) +
geom_histogram(binwidth=1) +
stat_bin(binwidth=1, geom='text', color='white', aes(label=..count..),
position=position_stack(vjust = 0.5))
resultant plot will be

Resources