如何使用ggplot绘制平滑填充图?基于现有数据集与代码求优化方案
Hey there! Let's spruce up that plot into a smoother, more polished filled visualization. Your current code creates a stacked proportional bar chart—here's how to shift to a sleek, smooth look, plus extra tweaks to make it pop:
Step 1: Prep your data for smooth stacked areas
First, we need to calculate proportional values (matching your position="fill" behavior) and their cumulative sums, which is essential for creating stacked smooth areas:
library(dplyr) library(ggplot2) # Calculate proportional and cumulative proportional values per period df_smooth <- df_test %>% group_by(period) %>% mutate(prop = value / sum(value), # Get percentage of total value per emotion cum_prop = cumsum(prop)) %>% # Cumulative sum for proper stacking ungroup() %>% arrange(period, emotie) # Sort to ensure stacking order is correct
Step 2: Create your smooth filled plot
We'll replace rigid bars with smooth, continuous fills. Below are two options depending on whether you want to keep period as your x-axis or shift to a continuous emotion axis:
Option 1: Faceted smooth stacked area plot (continuous emotion axis)
This view shows the flow of value proportions across emotion categories for each period, with smooth curves instead of sharp bar edges:
ggplot(df_smooth, aes(x = emotie, y = prop, fill = factor(emotie))) + geom_area(position = "stack", stat = "smooth", method = "loess", alpha = 0.8) + facet_wrap(~period) + # Split into separate panels for each period labs(x = "Emotion", y = "Proportion of Total Value", fill = "Emotion") + theme_minimal() + scale_fill_viridis_d(option = "plasma") # Colorblind-friendly palette
Option 2: Smooth "bar-like" filled shapes (period as x-axis)
If you want to retain period as your x-axis (matching your original plot structure) but with rounded, smooth edges:
ggplot(df_smooth, aes(x = as.numeric(period), y = cum_prop, group = factor(emotie), fill = factor(emotie))) + geom_ribbon(aes(ymin = lag(cum_prop, default = 0), ymax = cum_prop), alpha = 0.8, stat = "smooth", method = "loess") + scale_x_continuous(breaks = c(1,2), labels = c("Period 1", "Period 2")) + labs(x = "Period", y = "Cumulative Proportion", fill = "Emotion") + theme_minimal() + scale_fill_viridis_d(option = "mako")
Extra visual polish tips
- Adjust the
alphaparameter (e.g.,alpha = 0.7) to make fill colors semi-transparent, so overlapping smooth areas are easier to distinguish - Use a colorblind-friendly palette like
scale_fill_viridis_d()orscale_fill_brewer(palette = "Set2")instead of the default colors - Add descriptive axis labels and a clear legend title to help viewers understand the plot at a glance
- Swap
theme_minimal()fortheme_classic()ortheme_light()if you prefer a cleaner, less grid-heavy aesthetic - For the faceted plot, add
theme(strip.text = element_text(size = 12, face = "bold"))to make period labels stand out
内容的提问来源于stack exchange,提问作者Henk Straten

