如何使用ggplot2绘制发散式堆叠条形图?附可复现示例数据
Absolutely! You can definitely create a diverging stacked bar chart like the one you referenced using ggplot2. Below is a complete, reproducible example including sample data, quick data prep, and plotting code to match what you're looking for.
1. 准备环境与可复现示例数据
First, we’ll use the tidyverse package (which includes ggplot2 and handy data manipulation tools) and generate a consistent dataset with both positive and negative values—this is what creates the diverging "split" effect.
library(tidyverse) # Set seed to ensure data is reproducible every time you run the code set.seed(456) # Create sample data: Main categories with sub-categories that have positive/negative contributions df <- tibble( category = rep(c("Group 1", "Group 2", "Group 3", "Group 4"), each = 4), sub_category = rep(c("Factor A", "Factor B", "Factor C", "Factor D"), 4), value = c( # Group 1: 2 positive, 2 negative values runif(2, 10, 30), runif(2, -25, -5), # Group 2: 3 positive, 1 negative value runif(3, 5, 20), runif(1, -15, -5), # Group 3: 1 positive, 3 negative values runif(1, 15, 25), runif(3, -30, -10), # Group 4: 2 positive, 2 negative values runif(2, 20, 40), runif(2, -35, -15) ) )
2. 绘制水平发散堆叠条形图(贴合常见的"右侧"样式)
This code will generate a horizontal diverging stacked bar chart, where positive values stack to the right of the 0 line and negative values stack to the left—this is likely what you’re referring to as the "right-side" style:
ggplot(df, aes(y = category, x = value, fill = sub_category)) + # Stack bars automatically: positive values go right, negative go left geom_col(position = "stack", width = 0.7) + # Add a bold reference line at 0 to clearly separate positive/negative geom_vline(xintercept = 0, color = "black", linewidth = 1) + # Use a color palette that makes sub-categories easy to tell apart scale_fill_brewer(palette = "Paired") + # Add clear labels and a centered title labs( y = "Category", x = "Value", fill = "Sub-category", title = "Horizontal Diverging Stacked Bar Chart" ) + # Clean up the theme for better readability theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.title = element_text(size = 12), legend.position = "bottom" )
3. 绘制垂直版本(可选)
If you prefer a vertical layout, just swap the x and y aesthetics and adjust the reference line:
ggplot(df, aes(x = category, y = value, fill = sub_category)) + geom_col(position = "stack", width = 0.7) + geom_hline(yintercept = 0, color = "black", linewidth = 1) + scale_fill_brewer(palette = "Paired") + labs( x = "Category", y = "Value", fill = "Sub-category", title = "Vertical Diverging Stacked Bar Chart" ) + theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.title = element_text(size = 12), legend.position = "bottom" )
关键细节说明
- The magic happens with
geom_col()andposition = "stack": ggplot automatically handles stacking positive values in one direction and negative values in the opposite, creating the diverging effect from the 0 line. - You can tweak the color palette, bar width, or theme elements to match your specific design needs.
- The
set.seed()function ensures your sample data stays consistent every time you run the code, so your chart will look identical to the example.
内容的提问来源于stack exchange,提问作者rafa.pereira

