geom_curve alters order of geom_segment in ggplot

30 Views Asked by At

In ggplot the order of code on the y-axis is different when plotting only geom_segment and when plotting geom_segment with geom_curve.

library(tidyverse)

# create df --------------------------------------------------------------
df <- data.frame(
  code = c("A", "B", "C", "D", "E", "F"),
  code_order = c(2,1,3,4,6,5),
  start_year = c(2000, 2010, 2012, 2011, 2016, 2018),
  end_year = c(2010, 2024, 2020, 2024, 2024, 2020),
  leads_to = c("B", NA, "E, F", NA, "F", NA)
)

# connection df -----------------------------------------------------------
leads_to <- strsplit(df$leads_to, ", ")
names(leads_to) <- df$code
edges <- do.call(rbind, lapply(names(leads_to), function(x) cbind(rep(x, length(leads_to[[x]])), unlist(leads_to[x]))))
colnames(edges) <- c("from", "to")

# Create a new dataframe for the connections
df_connections <- data.frame(
  from = edges[, "from"],
  to = edges[, "to"]
)

df_connections$start_year_to <- df$start_year[match(df_connections$to, df$code)]
df_connections$start_year_from <- df_connections$start_year_to

# set order
df_final <- df_connections %>% 
  left_join(df, by = c("from" = "code")) %>% 
  mutate(code = from,
         code = fct_reorder(code, code_order, .desc = T),
         from = fct_reorder(from, code_order, .desc = T),
         to = fct_reorder(to, code_order, .desc = T))

# plot --------------------------------------------------------------------
ggplot() +
  geom_segment(data = df_final , aes(y = code, yend = code, x = start_year, xend = end_year), size = 3)

ggplot() +
  geom_segment(data = df_final , aes(y = code, yend = code, x = start_year, xend = end_year), size = 3) +
  geom_curve(data = df_final, aes(y = from, yend = to, x = start_year_from, xend = start_year_to))

Trying to resolve the issue I joined df and df_connections, and reordered all relevant variables using code_order.

How should the script be adjusted so that even with geom_curve the order of the segments remains as set in code_order?

1

There are 1 best solutions below

0
Dan On

You can try forcing proper order of variables by transforming code to a factor variable. Try:

df$code <- factor(df$code, levels = c("B", "A", "C", "D", "F", "E"))