1

I am trying to add labels above (for positive values)/below (for negative values) of the bars in a ggplot bar plot. But, the parameter 'vjust' seems to not be working properly.

I am using a code similar to this:

geom_text(aes_string(y=yCol,label=Labels), hjust=Data$BarLabJustX,vjust=Data$BarLabJustY,na.rm=T)

In my data.frame 'Data', I set BarLabJustX='middle', BarLabJustY='top' for posotive data and BarLabJustY='bottom' for negative data. It seems working on some graphs, and not on others.

Here are a couple of examples:

enter image description here

enter image description here

UPDATE: I found out this problem could be fixed by using the 'BarLabJustY' column inside the mapping (as they are introduced inside the source data.frame):

geom_text(aes_string(y=yCol,label=Labels,hjust='BarLabJustX',vjust='BarLabJustY'),na.rm=T)

I still don't know why this changes the way the code behaves.

enter image description here

Ben
  • 103
  • 1
  • 10

1 Answers1

2

vjust (and hjust) can have unpredictable behavior when set to values outside the range of 0 to 1 (see here for details). I'm not sure why the string values are behaving differently in different facets. Instead, you might try directly setting the locations of the labels with the y aesthetic in geom_text. For example:

# Fake data
set.seed(2)
dat = data.frame(id=1:10, val=rnorm(10))
rng = diff(range(dat$val))

ggplot(dat, aes(id, val)) + 
  geom_col() +
  geom_text(aes(label=round(val,1), 
                y = ifelse(val < 0, val - 0.05*rng, val + 0.05*rng)),
            colour="red", size=4) +
  theme_bw()

enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • Thanks for the respons. Please see my update. I needed something that would work with a wide range of data so I don't need to each time decide how much gap I need between the labels and the bars. Cheers. – Ben Jul 23 '19 at 06:38
  • 1
    In my answer I tried to automate label placement by making the distance a fraction of the range of the data. Thus, it's automatically normalized to whatever the range of your data happens to be for a given plot. However, if you're able to get `vjust` to work the way you want, then that's certainly simpler. – eipi10 Jul 23 '19 at 22:38