企业内部人员流动Alluvial Plot绘制异常:图形无部门连接
Hey there! Let's sort out why your alluvial plot is looking flat and get it showing proper connections between departments. The core issue here is that your current dataset doesn't define complete 3-node paths (Source → Middle → Target) — the structure alluvial plots rely on to draw meaningful flow connections. Right now, you’ve split incoming and outgoing staff movements into separate rows without linking them to the three-axis structure you want.
Step 1: Understand the Data Structure Problem
Your data mixes "incoming source" and "outgoing target" labels in the same action_reason column, with no clear journey through your three intended axes:
- Axis 1: Personnel Source
- Axis 2: Transfer/Outflow Start Department
- Axis 3: Final Destination
To fix this, we need to restructure every row to represent a full path through these three axes.
Step 2: Restructure Your Data
First, let’s clean up inconsistent labels (like the unlabeled "Sales" entry in outgoing flows) and build complete flow paths:
# Load required packages library(tidyverse) library(ggalluvial) # Your original dataset set.seed(1) df <- tibble( c("Moved in", "Moved in", "Moved in", "Moved in", "Moved out", "Moved out", "Moved out", "Moved out", "Moved out"), c("Functions", "Functions", "Functions", "Functions", "Functions", "Functions", "Functions", "Functions", "Functions"), c("From Functions", "From Sales", "From Supply", "From Commercial","To Group", "To Products", "Sales", "To Supply", "To Commercial"), c(rpois(9, 5)), .name_repair = ~c("move","area","action_reason","Freq") ) # Restructure data into 3-axis flow paths df_clean <- df %>% # Fix inconsistent outgoing label (add "To " to standalone "Sales") mutate(action_reason = ifelse(move == "Moved out" & action_reason == "Sales", "To Sales", action_reason)) %>% # Build full 3-node paths for incoming and outgoing flows mutate( # Incoming flows: [Source Dept] → Functions → Functions (staff moving into Functions) source = ifelse(move == "Moved in", str_remove(action_reason, "From "), area), middle = area, # Outgoing flows: Functions → Functions → [Target Dept] (staff leaving Functions) target = ifelse(move == "Moved out", str_remove(action_reason, "To "), area) ) %>% # Keep only columns needed for the plot select(source, middle, target, Freq)
Step 3: Draw the Proper Alluvial Plot
Now use ggalluvial to create your 3-axis plot with connected flows:
ggplot(df_clean, aes(y = Freq, axis1 = source, axis2 = middle, axis3 = target)) + # Draw colored flow bands between nodes geom_alluvium(aes(fill = source), width = 1/12) + # Draw solid nodes for each axis geom_stratum(width = 1/12, fill = "white", color = "black") + # Add labels to each node geom_text(stat = "stratum", aes(label = after_stat(stratum))) + # Set axis titles matching your requirements scale_x_discrete(limits = c("Personnel Source", "Transfer Start Dept", "Final Destination"), expand = c(0.05, 0.05)) + # Use a color palette for readability scale_fill_viridis_d(option = "plasma") + labs(title = "Staff Flow: Source → Transfer Dept → Final Destination", fill = "Source Department") + theme_minimal()
Why This Works
- We transformed every row into a full 3-node path, so the plot recognizes how flows connect across all three axes.
- Incoming flows are structured as
[External Source] → Functions → Functions(representing staff joining and staying in Functions). - Outgoing flows are structured as
Functions → Functions → [Destination](representing staff leaving Functions for other departments). - The
geom_alluviumnow has clear, continuous paths to draw, eliminating the flat, disconnected look from your original data.
内容的提问来源于stack exchange,提问作者Nemo

