1
votes

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 :

enter image description here

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) )

enter image description here

Does anybody have a solution? I would be very greatful

2
One thing that I'm seeing while messing around with this is that it seems to be partly typographical. The asterisk is slightly superscript; change the label argument to something like "o" or "I" to see that. I'm thinking there might be a unicode you can use instead for a star shape that is centeredcamille
I does make a difference- thanks!Aron

2 Answers

4
votes

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)

enter image description here

1
votes

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).