如何在R语言中创建堆叠瀑布图(stacked waterfall chart)?
Great question! Stacked waterfall charts are definitely trickier to pull off in R compared to standard ones, but you don’t have to settle for clunky stacked bar charts. Here are two polished approaches to get the exact visualization you want:
1. Manual Implementation with ggplot2
The core idea is to calculate the starting position for each stacked segment, so each block flows from the end of the previous one (just like a standard waterfall, but stacked). Here’s a step-by-step example:
Step 1: Prepare and Process Data
First, we’ll create sample data and compute the necessary starting positions for each group and category:
library(ggplot2) library(dplyr) # Create sample data (adjust to match your actual dataset) set.seed(123) df <- tibble( category = rep(c("Start", "Increase A", "Decrease B", "Increase C", "End"), each = 2), group = rep(c("Revenue", "Costs"), 5), value = c(100, 100, 20, -15, -10, 25, 30, -20, 130, 110) ) # Calculate cumulative values and starting positions for each stacked segment df_processed <- df %>% group_by(category) %>% mutate(cum_group = cumsum(value), segment_start = lag(cum_group, default = 0)) %>% ungroup() %>% group_by(group) %>% mutate(group_running_total = cumsum(ifelse(category == "Start", 0, lag(value, default = 0)))) %>% ungroup() %>% mutate(actual_start = group_running_total + segment_start)
Step 2: Build the Stacked Waterfall Chart
Use geom_rect to plot each stacked segment, since it lets us define exact start/end positions:
ggplot(df_processed, aes(x = category)) + # Plot stacked waterfall segments geom_rect(aes( xmin = as.integer(category) - 0.4, xmax = as.integer(category) + 0.4, ymin = actual_start, ymax = actual_start + value, fill = group ), color = "white", linewidth = 0.5) + # Add value labels centered in each segment geom_text(aes( y = actual_start + value / 2, label = ifelse(value != 0, value, ""), color = group ), size = 4, fontface = "bold") + # Customize aesthetics scale_x_discrete(expand = c(0.1, 0.1)) + scale_fill_brewer(palette = "Set2") + scale_color_brewer(palette = "Set2") + labs(title = "Stacked Waterfall Chart (Static)", x = "Stage", y = "Total Value") + theme_minimal() + theme(legend.position = "top")
This method gives you full control over the chart’s appearance and preserves the waterfall’s signature "flow" between categories.
2. Interactive Stacked Waterfall with plotly
If you want an interactive version (great for exploring data), plotly can handle stacked waterfalls by setting the base parameter for each trace to the cumulative total of the previous group:
library(plotly) # Calculate base values for the second group base_values <- df_processed %>% filter(group == "Revenue") %>% mutate(base = actual_start + value) %>% pull(base) # Build interactive chart plot_ly() %>% add_trace( data = df %>% filter(group == "Revenue"), x = ~category, y = ~value, type = "waterfall", name = "Revenue", measure = ~ifelse(category %in% c("Start", "End"), "total", "relative"), marker = list(color = "#619CFF") ) %>% add_trace( data = df %>% filter(group == "Costs"), x = ~category, y = ~value, type = "waterfall", name = "Costs", measure = ~ifelse(category %in% c("Start", "End"), "total", "relative"), base = ~base_values, marker = list(color = "#F8766D") ) %>% layout( title = "Interactive Stacked Waterfall Chart", xaxis = list(title = "Stage"), yaxis = list(title = "Total Value"), barmode = "stack", legend = list(x = 0.1, y = 1.1, orientation = "h") )
Why This Beats Stacked Bar Charts
Stacked bar charts start every segment at 0, which hides the cumulative flow that makes waterfall charts useful. These methods maintain the waterfall’s core purpose—showing how each category contributes to the total change—while adding the stacked group breakdown you need.
内容的提问来源于stack exchange,提问作者saurav shekhar

