Natalie O'Shea
Natalie O'Shea

Reputation: 327

Alter right node y-axis position in parellel sets diagram {ggforce}

I am struggling to figure out how to alter the position of the right node in a parallel sets diagram. I would like all the ribbons on the left to flow to the right node in a centered-aligned position rather than bottom-aligned, as shown in the example below. Does anyone know if this is possible with ggforce?

I tried altering the position using position = position_nudge(y = 1) but this approach didn't work as it moves the entire diagram rather than a single node.

# load libraries
library(tidyverse)
library(ggforce)

# create example data frame
example_data <- tibble::tribble(
  ~predictor,    ~outcome, ~weight,  ~color1, ~color2,
    "pred_1", "outcome_1",    0.05, "#49B5AE", "#FF5E2B",
    "pred_2", "outcome_1",    0.32, "#49B5AE", "#FF5E2B",
    "pred_3", "outcome_1",    0.22, "#49B5AE", "#FF5E2B",
    "pred_4", "outcome_1",    0.13, "#37B4FF", "#FF5E2B",
    "pred_5", "outcome_1",    0.17, "#37B4FF", "#FF5E2B",
    "pred_6", "outcome_1",    0.11, "#37B4FF", "#FF5E2B"
  )

# create alluvial data frame
alluvial <- example_data |>
  # gather into alluvial data frame
  gather_set_data(c("predictor", "outcome")) |>
  # set factor levels for x-axis
  mutate(x = factor(x, levels = c("predictor", "outcome")))

# set axis width and separation parameters
aw <- 0.05
sp <- 0.25

# create visualization
ggplot(alluvial, aes(x = x, id = id, split = y, value = weight)) +
  geom_parallel_sets(aes(fill = I(fct_rev(color1))), # reverse factor order for colors
                     # position = position_nudge(y = 1), # no way to nudge only right node
                     axis.width = aw, sep = sp) +
  geom_parallel_sets_labels(data = alluvial |> filter(x == "predictor"),
                            aes(color = I(color1)), 
                            size = 3, angle = 0, hjust = 1,
                            axis.width = aw, sep = sp) +
  geom_parallel_sets_labels(data = alluvial |> filter(x == "outcome"),
                            aes(color = I(color2)), 
                            size = 3, angle = 0, hjust = 0, fontface = "bold",
                            axis.width = aw, sep = sp) +
  theme_void()

parallel sets diagram

Upvotes: 1

Views: 214

Answers (1)

Allan Cameron
Allan Cameron

Reputation: 174468

I don't think you can do this with geom_parallel_sets. However, it's easy enough to do with ggsankey:

remotes::install_github("davidsjoberg/ggsankey")
library(tidyverse)
library(ggsankey)

make_long(example_data, predictor, outcome, value = weight) |>
  mutate(node = fct_rev(node)) |>
  ggplot(aes(x = x, 
             next_x = next_x, 
             node = node, 
             next_node = next_node,
             value = value,
             fill = factor(node))) +
  geom_sankey(width = 0) +
  geom_sankey_text(aes(label = node, color = fct_rev(node)), hjust = 1.2) +
  scale_fill_manual(values = c(NA, rep(c("#49B5AE", "#37B4FF"), each = 3)),
                    guide = "none") +
  scale_color_manual(values = c(NA, rep(c("#49B5AE", "#37B4FF"), each = 3)),
                    guide = "none", na.value = "#00000000") +
  annotate("text", x = 2, y = 0, label = "Outcome 1", hjust = -0.2,
           color = "#FF5E2B") +
  theme_void()

enter image description here

Upvotes: 1

Related Questions