2

I'm working in ggplot. I created a bar chart but the labels over the bars are not centered over the bars (see figure).

How do I center each bars' label over its respective bar in this plot?

enter image description here

Here is the code:

df<- structure(list(Cycle = c(1980, 1982, 1984, 1986, 1988, 1990, 
                         1992, 1994, 1996, 1998, 2000, 2002, 2004, 2006, 2008, 2010, 2012, 
                         2014, 2016, 1980, 1982, 1984, 1986, 1988, 1990, 1992, 1994, 1996, 
                         1998, 2000, 2002, 2004, 2006, 2008, 2010, 2012, 2014, 2016), 
               Donor_Location = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                            1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
                                            2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                            2L), .Label = c("In District", "Out of District"), class = "factor"), 
               Count_Percentage_Mean = c(0.167598290871218, 0.124829496296588, 
                                         0.0940731004562636, 0.125521769946444, 0.134545184854301, 
                                         0.221904402021545, 0.241031685849158, 0.284978425863672, 
                                         0.280387277343076, 0.269095218446438, 0.273131304975636, 
                                         0.288912758780087, 0.297134465175358, 0.296786491472909, 
                                         0.292365465524159, 0.303877491711499, 0.249983664094922, 
                                         0.258636305966848, 0.239182241578899, 0.159250631842859, 
                                         0.161311478778858, 0.157209833306125, 0.161853462566676, 
                                         0.174277618030726, 0.251786815739142, 0.318324841334214, 
                                         0.312697665544327, 0.347430615609066, 0.346833684171301, 
                                         0.374139881841685, 0.422610276126137, 0.432433986875512, 
                                         0.424992976111316, 0.429557833404775, 0.443001597806887, 
                                         0.462424440669885, 0.45460402775165, 0.492540191333363)), row.names = c(NA, 
                                                                                                                 -38L), class = "data.frame")


ggplot(df, aes(x = Cycle , y = Count_Percentage_Mean, fill = Donor_Location)) +
  geom_bar(stat = "identity", position = 'dodge') +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  geom_text(aes(label=paste(round(Count_Percentage_Mean*100,0), "%", sep = "")), position=position_dodge(width=0.9), vjust=-0.5)

Thank You!

Sharif Amlani
  • 1,138
  • 1
  • 11
  • 25
  • See the second answer to this [question](https://stackoverflow.com/questions/40211451/geom-text-how-to-position-the-text-on-bar-as-i-want): "The position_dodge() statement takes a width parameter. To ensure that the text is centred at the end of the bars (i.e., the dodging width for the bars and the text to be the same), give the same width parameter to the position_dodge() statement within geom_bar and within geom_text." – Maël Dec 02 '21 at 09:55

2 Answers2

4

Hm. Unfortuantely I can't tell you what's the reason for this issue. Also, I'm not aware of any update of ggplot2 or ... Probably I miss something basic (maybe I need another cup of coffee). Anyway. I had a look at the layer_data and your text labels are simply dodged by only half the width of the bars. Hence, you could achieve your desired result by doubling the width, i.e. use position = position_dodge(width = 1.8) in geom_text

library(ggplot2)

ggplot(df, aes(x = Cycle, y = Count_Percentage_Mean, fill = Donor_Location)) +
  geom_col(position = "dodge") +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  geom_text(aes(label = scales::percent(Count_Percentage_Mean, accuracy = 1)), position = position_dodge(width = 1.8), vjust = -0.5)

stefan
  • 90,330
  • 6
  • 25
  • 51
2

Try adjusting position_dodge(width = 2.1) for both geom_bar and geom_text

library(ggplot2)
ggplot(df, aes(x = Cycle , y = Count_Percentage_Mean, fill = Donor_Location)) +
  geom_bar(stat = "identity", position = position_dodge(width = 2.01)) +
  scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
  geom_text(aes(label = paste(round(Count_Percentage_Mean * 100, 0), "%", sep = "")), 
            position = position_dodge(width = 2.01), vjust = -0.5,
            size = 2)+
  theme(legend.position = "bottom")

Created on 2021-12-02 by the reprex package (v2.0.1)

Peter
  • 11,500
  • 5
  • 21
  • 31