ggplot2离散刻度密度图:无法消除轴与图间距(expand参数无效)
解决ggplot2密度脊线图中y轴分类与x轴间距无法消除的问题
问题描述
我有一个包含liking和value两列的tibble数据集,使用ggplot2绘制密度脊线图时,尝试通过scale_y_discrete的expand参数(包括expand_scale、c(0,0)、expansion(0,0))消除var1与x轴的间距,但均未生效。
数据集样例:
> head(datplot) # A tibble: 6 × 2 liking value <chr> <dbl> 1 var1 -1.85 2 var2 2.27 3 var1 -1.98 4 var2 1.96 5 var1 -1.95 6 var2 1.80
原绘图代码:
p1 <- ggplot(datplot, aes(x=value, y=factor(liking, level = c("var1", "var2")), group = liking, color = liking)) + scale_y_discrete(expand = expand_scale(mult = c(0.1, 1))) + geom_rect(data=data.frame(), inherit.aes = FALSE, mapping = aes( ymin = 0, ymax = Inf, xmin = -0.1 * min(stdev), xmax = 0.1 * max(stdev) ), fill = "black", alpha = 0.1) + geom_density_ridges(scale = 0.75, size = 0.5, alpha=0.5, show.legend = FALSE, quantile_lines = TRUE, quantiles = c(0.025, 0.5, 0.975), vline_color = alpha("white", 0.5), aes(fill = liking)) + scale_color_manual(values = c("#cc2701", "#004d8d"), breaks = c("var1", "var2")) + scale_fill_manual(values = c("#cc2701", "#004d8d"), breaks = c("var1", "var2")) + labs(title="ggplot title") + ylab("liking") + xlab("values") + theme()
问题根源
geom_rect强制扩展y轴范围:代码中geom_rect的ymin = 0会让ggplot自动将y轴范围向下扩展到0,而var1对应的y轴位置是1,因此两者之间产生了间距;scale_y_discrete参数被覆盖:由于geom_rect已经修改了y轴的整体范围,单独设置scale_y_discrete的expand参数无法生效。
解决方案
修正步骤
- 调整
geom_rect的ymin为var1对应的y轴位置(即1),避免不必要的y轴范围扩展; - 正确设置
scale_y_discrete的expand参数为expansion(0, 0),消除y轴两端的空白; - 可选:使用
coord_cartesian严格锁定y轴范围,防止其他元素意外扩展轴范围。
修正后的代码
# 先定义stdev变量(示例为计算value列的标准差,可根据实际情况调整) stdev <- sd(datplot$value) p1 <- ggplot(datplot, aes(x=value, y=factor(liking, level = c("var1", "var2")), group = liking, color = liking)) + # 设置y轴无扩展间距 scale_y_discrete(expand = expansion(0, 0)) + # 调整geom_rect的ymin为1(对应var1的y轴位置) geom_rect(data=data.frame(), inherit.aes = FALSE, mapping = aes( ymin = 1, ymax = Inf, xmin = -0.1 * stdev, xmax = 0.1 * stdev ), fill = "black", alpha = 0.1) + geom_density_ridges(scale = 0.75, size = 0.5, alpha=0.5, show.legend = FALSE, quantile_lines = TRUE, quantiles = c(0.025, 0.5, 0.975), vline_color = alpha("white", 0.5), aes(fill = liking)) + scale_color_manual(values = c("#cc2701", "#004d8d"), breaks = c("var1", "var2")) + scale_fill_manual(values = c("#cc2701", "#004d8d"), breaks = c("var1", "var2")) + labs(title="ggplot title") + ylab("liking") + xlab("values") + # 可选:严格锁定y轴范围,避免意外扩展 coord_cartesian(ylim = c(1, 2), expand = FALSE) + theme()
额外优化
如果密度脊线本身与y轴分类标签之间仍有间距,可以调整geom_density_ridges的scale参数(例如设为1),或者添加rel_min_height = 0参数确保脊线底部完全贴合对应的y轴位置。
内容的提问来源于stack exchange,提问作者Unai Vicente
相关产品推荐
相关产品推荐

