Reputation: 89
Hi I am struglling with getting labels in a grouped horizontal barplot in the right position. I know that there have been similar questions before but I dont seem to ge the answers to work.
My data ("Correlation") looks like this:
Trait r se Disease significant
1 0.4 0.06 A *
1 0.1 0.06 B
1 -0.05 0.03 C
2 0.4 0.06 A *
2 0.1 0.05 B
2 -0.06 0.03 C *
3 0.04 0.06 A *
3 0.2 0.05 B *
3 0.3 0.04 C *
And my code:
grouped_plot <- ggplot(data=Correlation, aes(x=Trait, y=r,
fill=Disease)) + geom_bar(stat="identity", position="dodge",
width=0.9)+ geom_errorbar(aes(ymin = r - se, ymax = r + se),
width = 0.3, position=position_dodge(0.9), stat="identity",
color=rgb(100,100,100, maxColorValue = 255)) + coord_flip() +
theme_minimal() +
scale_y_continuous(breaks=seq(-0.8,0.8,by=0.1)) +
theme(legend.position="none") + ggtitle("XXX") + theme(plot.title =
element_text(size=11) )
grouped_plot + geom_text(aes(x=Trait, y=r + 0.07 * sign(r),
label=format(significant), hjust=ifelse(r>0,0,1)),
position=position_dodge(0.9), size=5, color=rgb(100,100,100,
maxColorValue = 255) )
But howevery I adjust the parameters, the stars are never quite centered vertically + the distance to the errorbars is different each time :
Adding "se" to the y-parameter in geom_text also doesnt make the stars to be in the same distance to the error-bars ( for the error-bars that go in the negative direction )
grouped_plot + geom_text(aes(x=Trait, y=r +se + 0.01 * sign(r),
label=format(significant), hjust=ifelse(r>0,0,1)),
position=position_dodge(0.9), size=5, color=rgb(100,100,100, maxColorValue
= 255) )
Does anybody have a solution? I would be very greatful
Upvotes: 1
Views: 2256
Reputation: 16832
Like I mentioned in a comment above, I think there's a typographical issue: the asterisk character is set in a slight superscript, so it hovers above the center line you'd expect it to be on. Rather than using that specific character, I tried using a geom_point
to get a little more control than the geom_text
, then mapped the significance variable to shape. I changed the data slightly, to make a column is_sig
that would have values for every observation, because I was having trouble getting things lined up when there were NA
values (makes the dodging difficult).
The other trick I used was for positioning just outside the errorbars, taking sign into account. I set a variable gap
to keep a uniform offset for each star, then in the geom_point
, calculate the y position as r
plus or minus the standard error + gap.
Mess around with the shape used; this was the closest to your asterisk I could get quickly, but there might be a unicode character that you can put in instead. On my Mac, I can easily get a star character, but you need an extra step to get that unicode character to show in the plot. Check out the shape reference also.
In the geom_point
, set show.legend = F
to keep the points from showing up in the legend. Or omit this, and create a shape legend to show what the asterisk means. Note the warning that those NA
shapes are being removed.
library(dplyr)
library(readr)
library(ggplot2)
# ... reading data
df2 <- df %>%
mutate(is_sig = ifelse(is.na(significant), "not significant", "significant"))
gap <- 0.01
ggplot(df2, aes(x = as.factor(Trait), y = r, fill = Disease, group = Disease)) +
geom_col(position = position_dodge(width = 0.9), width = 0.9) +
geom_errorbar(aes(ymin = r - se, ymax = r + se), position = position_dodge(width = 0.9), width = 0.3) +
geom_point(aes(shape = is_sig, y = r + sign(r) * (se + gap)), position = position_dodge(width = 0.9),
size = 2, show.legend = F) +
coord_flip() +
scale_shape_manual(values = c("significant" = 8, "not significant" = NA))
#> Warning: Removed 3 rows containing missing values (geom_point).
Created on 2018-07-30 by the reprex package (v0.2.0).
Upvotes: 1
Reputation: 17648
play around with one value of hjust
and some angle
outside aes
ggplot(data=d, aes(x=Trait, y=r, fill=Disease)) +
geom_col(position = position_dodge(width = 0.9), show.legend = F)+
geom_errorbar(aes(ymin = r - se, ymax = r + se),
width = 0.3, position=position_dodge(width=0.9)) +
coord_flip() +
scale_y_continuous(breaks=seq(-0.8,0.8,by=0.1)) +
theme_minimal() +
geom_text(aes(x=Trait, y=r + se + 0.01 * sign(r),
label=format(significant)), position=position_dodge(width = 0.9),
angle =270, hjust=.3)
Upvotes: 4