Search code examples
rggplot2geom-bargeom-text

geom_text how to position the text on bar as I want?


I would like to adjust the text on the barplot.

I tried to adjust hjust/vjust to display as I like it but it seems like it's not working properly.

ggplot(data) + 
        geom_bar(aes(name, count, 
        fill = week), stat='identity', position = 'dodge') +
        geom_text(aes(name,count, 
        label=count),hjust=0.5, vjust=3, size=2,
        position = position_dodge(width = 1)) + 
        coord_flip()

enter image description here

So I would like the numbers to situate on each bar, in the middle, at the right-edge so it's readable without overlapping like the last parts.


Solution

  • Edit:

    The easier solution to get hjust/vjust to behave intelligently is to add the group aesthetic to geom_text and then hjust & position adjust for the group automatically.

    1. Vertical Orientation

    ggplot(data) + 
      geom_bar(
        aes(x = name, y = count, fill = week, group = week), 
        stat='identity', position = 'dodge'
      ) +
      geom_text(
        aes(x = name, y = count, label = count, group = week),
        position = position_dodge(width = 1),
        vjust = -0.5, size = 2
      ) + 
      theme_bw()
    

    This gives:

    enter image description here

    2. Horizontal Orientation

    ggplot(data) + 
      geom_bar(
        aes(x = name, y = count, fill = week, group = week), 
        stat='identity', position = 'dodge'
      ) +
      geom_text(
        aes(x = name, y = count, label = count, group = week), 
        hjust = -0.5, size = 2,
        position = position_dodge(width = 1),
        inherit.aes = TRUE
      ) + 
      coord_flip() + 
      theme_bw()
    

    This gives:

    enter image description here


    This is not necessarily the most general way to do this, but you can have a fill dependent hjust (or vjust, depending on the orientation) variable. It is not entirely clear to me how to select the value of the adjustment parameter, and currently it is based on what looks right. Perhaps someone else can suggest a more general way of picking this parameter value.

    1. Vertical Orientation

    library(dplyr)
    library(ggplot2)
    
    # generate some data
    data = data_frame(
      week = as.factor(rep(c(1, 2), times = 5)),
      name = as.factor(rep(LETTERS[1:5], times = 2)),
      count = rpois(n = 10, lambda = 20),
      hjust = if_else(week == 1, 5, -5),
      vjust = if_else(week == 1, 3.5, -3.5)
    )
    
    # Horizontal
    ggplot(data) + 
      geom_bar(
        aes(x = name, y = count, fill = week, group = week), 
        stat='identity', position = 'dodge'
      ) +
      geom_text(
        aes(x = name, y = count, label = count, vjust = vjust), 
        hjust = -0.5, size = 2,
        inherit.aes = TRUE
      ) + 
      coord_flip() + 
      theme_bw() 
    

    Here is what that looks like:

    enter image description here

    2. Horizontal Orientation

    ggplot(data) + 
      geom_bar(
        aes(x = name, y = count, fill = week, group = week), 
        stat='identity', position = 'dodge'
      ) +
      geom_text(
        aes(x = name, y = count, label = count, vjust = vjust), 
        hjust = -0.5, size = 2,
        inherit.aes = TRUE
      ) + 
      coord_flip() + 
      theme_bw()
    

    Here is what that looks like:

    enter image description here