Home > Software design >  How to right align geom_text_repel labels
How to right align geom_text_repel labels

Time:08-21

I'm working with the following data

df <- tibble(
  year = c(
    2016, 2019, 2020, 2020,
    2016, 2018, 2018, 2020,
    2020, 2018, 2020, 2020,
    2018, 2019, 2019, 2017,
    2019, 2018, 2017, 2019),
  category = c(rep("A", 2), rep("B", 2), rep("C", 5), rep("D", 11)),
  amount = c(
    -4622,-26.32,-3351.76,-163.4109162,-108.6,-103.82,-1258,-460.66391692,
    -374.93383968,-9,-3500.11,-318.0851145,-1075.16,
    214,-4237.07,-94.94,-1391.56,-42.547185,-846,-2833.49))

I would like to create a bar plot that labels each of the bar segements. I'm using geom_repel_text to move labels up/down the y axis so that the labels don't overlap. I would also like to nudge all the labels to the right of their bar.

The problem is that I want all the labels to be right aligned. How can I do this?

See the image below for how I would like to right-align the labels for each year.

enter image description here

Here's the code I've used so far to create the graph

df %>%
  group_by(year, category) %>% 
  summarise(amount = abs(sum(amount))) %>% 
  ggplot(
    aes(
      x = year,
      y = amount,
      label = round(amount),
      fill = category))  
  geom_col(
    aes(),
    colour = "#000000",
    size = .05,
    width = 0.4)  
  ggrepel::geom_text_repel(
    position = position_stack(vjust = 0.5),
    direction = "y",
    vjust = 1,
    size = 4.5)  
  scale_y_continuous(limits = c(0, 35000))   
  scale_x_continuous(
    n.breaks = 7,
    expand = expansion(mult = c(0.125, 0.125)))  
  ggplot2::coord_cartesian(clip = 'off')

CodePudding user response:

One option would be to manually compute the positions for the stacked labels which allow you to use nudging to shift the labels and finally use hjust=1 to right align your labels.

library(dplyr)
library(ggplot2)
library(ggrepel)

dat <- df %>%
  group_by(year, category) %>% 
  summarise(amount = abs(sum(amount)))

dat <- dat |> 
  group_by(year) |> 
  arrange(year, desc(category)) |> 
  mutate(amount_cum = cumsum(amount),
         amount_cum = .5 * (amount_cum   lag(amount_cum, default = 0)))

  ggplot(dat,
    aes(
      x = year,
      y = amount,
      label = round(amount),
      fill = category))  
  geom_col(
    aes(),
    colour = "#000000",
    size = .05,
    width = 0.4)  
  ggrepel::geom_text_repel(aes(y = amount_cum),
    nudge_x = .5,
    direction = "y",
    vjust = .5,
    hjust = 1,
    size = 4.5)  
  scale_y_continuous(limits = c(0, 35000))   
  scale_x_continuous(
    n.breaks = 7,
    expand = expansion(mult = c(0.125, 0.125))
  )  
  ggplot2::coord_cartesian(clip = 'off')

enter image description here

  • Related