如何基于随机值矩阵实现每列含最小阈值的Waterfall(瀑布图)
Hey there! Let's tackle this problem step by step. You've got a random matrix and want to create a waterfall chart with per-column minimum thresholds—here's a solid R-based solution using ggplot2, which is super flexible for custom visualizations.
1. 准备工作与数据预处理
First, we'll convert your wide-format matrix into a tidy long-format data frame, then calculate the minimum threshold for each column and compute the necessary values for the waterfall chart.
# Load required packages (install first if you haven't: install.packages("tidyverse")) library(tidyverse) # Your original matrix generation code set.seed(1) n_rows <- 6 n_cols <- 5 mat_random <- matrix(runif(n = 30, 0.04, 0.06), n_rows, n_cols) # Convert matrix to tidy data frame and calculate thresholds df <- mat_random %>% as.data.frame() %>% # Add stage labels for each row mutate(Stage = paste0("Stage_", 1:n_rows)) %>% # Reshape to long format (easier for grouping/plotting) pivot_longer(cols = -Stage, names_to = "Group", values_to = "Value") %>% # Group by each column (Group) and compute its minimum threshold group_by(Group) %>% mutate( Threshold = min(Value), # Calculate difference between each value and the column's threshold Diff_from_threshold = Value - Threshold )
2. 两种瀑布图实现方案
方案A:展示各阶段与阈值的差异
This chart shows how each stage's value deviates from the minimum threshold of its column, with each column (group) in its own subplot for clarity.
ggplot(df, aes(x = Stage, y = Diff_from_threshold, fill = Stage)) + # Bar chart for threshold differences geom_col(position = "identity") + # Add labels for the difference values geom_text(aes(label = round(Diff_from_threshold, 5)), vjust = -0.5, size = 3) + # Create a subplot for each column/group facet_wrap(~Group, scales = "free_y") + # Customize labels and theme labs( title = "Waterfall Chart: Stage vs. Column Minimum Threshold", y = "Difference from Column Threshold", x = "Stage" ) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1))
方案B:累计式瀑布图(从阈值开始累加)
If you want to show cumulative changes starting from the column's minimum threshold, this version tracks the running total and marks the threshold with a dashed red line.
# Calculate cumulative values for the waterfall df_cumulative <- df %>% group_by(Group) %>% mutate( # Cumulative value starting from the threshold Cumulative = Threshold + cumsum(Diff_from_threshold), # Previous stage's cumulative value (starts at threshold) Previous = lag(Cumulative, default = Threshold), # Change between current and previous stage Cumulative_diff = Cumulative - Previous ) # Plot the cumulative waterfall ggplot(df_cumulative, aes(x = Stage, y = Cumulative_diff, fill = ifelse(Cumulative_diff > 0, "Increase", "Decrease"))) + geom_col(position = "identity") + # Label the final cumulative value for each stage geom_text(aes(label = round(Cumulative, 5)), vjust = ifelse(Cumulative_diff > 0, -0.5, 1.5), size = 3) + # Add dashed line for the column's minimum threshold geom_hline(aes(yintercept = Threshold), linetype = "dashed", color = "red") + facet_wrap(~Group, scales = "free_y") + labs( title = "Cumulative Waterfall Chart with Column Minimum Threshold", y = "Cumulative Value", x = "Stage", fill = "Change Direction" ) + # Custom color scheme for increases/decreases scale_fill_manual(values = c("Increase" = "#2ecc71", "Decrease" = "#e74c3c")) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1))
自定义调整提示
- If you want to use a fixed global threshold instead of per-column minima, replace
Threshold = min(Value)withThreshold = [your fixed value](e.g.,Threshold = 0.04). - Adjust the rounding precision in
round()to match your needs. - Tweak colors, labels, or themes to align with your visualization requirements.
内容的提问来源于stack exchange,提问作者Sam

