Search code examples
ggplot2text-alignmentgeom-text

How to align text differently within same geom_-element in ggplot2


I am encountering a problem when I want to label the starting and ending point of a line graph indicating a duration with ggplot2. Certain labels are aligned "outward", others "inward". I cannot figure out why that is and how to solve this issue.

Here is an example code illustrating the issue:

library(dplyr)
library(stringr)
library(ggplot2)
library(lubridate)
library(tidyr)

Dur <- tibble(Country = c('Country1', 'Country2'),
              start = c(18836, 18523) %>% as_date,
              end = c(19034, 18865) %>% as_date)

Dur %>% 
  pivot_longer(-1, values_to = "Dates") %>% 
  mutate(label.text = Dates %>% 
           format("%B %d") %>% 
           str_remove("(?<=.{3}).+(?= )")) %>% # this part extracts the first 3 letters of each month and the day
  ggplot(aes(x = Dates, y = Country, label = label.text)) +
  geom_line(linewidth = 0.6, color = "red") +
  geom_text(hjust = "outward") +
  scale_x_date(limits = c(as_date(Dur$start %>% min)-30,
                          as_date(Dur$end %>% max)+30),
               date_breaks = "3 month", date_labels = "%d/%m/%Y") +
  theme_bw()

In "Country 1", the starting date is aligned inward even though I specfically asked for "outward". I hoped to have all labels outward.

What can I do differently?

Thanks in advance!


Solution

  • hjust works inside aes() ,so we could create a pos column to specify where we want the text.

      Dur %>% 
        pivot_longer(-1, values_to = "Dates") %>% 
        mutate(label.text = Dates %>% 
                 format("%B %d") %>% 
                 str_remove("(?<=.{3}).+(?= )"),
               pos = ifelse(name == "start", 1, 0) ) %>% # position to pass to aes 
        ggplot(aes(x = Dates, y = Country)) +
        geom_text(aes(label = label.text, hjust = pos)) +
        geom_line(linewidth = 0.6, color = "red") +
        scale_x_date(limits = c(as_date(Dur$start %>% min)-30,
                                as_date(Dur$end %>% max)+30),
                     date_breaks = "3 month", date_labels = "%d/%m/%Y") +
        theme_bw()
    

    Created on 2023-04-20 with reprex v2.0.2