You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用stat_density_2d绘制的二维密度图异常问题求助

解决stat_density_2d边缘截断与空白区域问题

从你的数据和代码来看,图表出现的两个问题原因不同,我们分别来解决:

1. 边缘截断问题

边缘截断是因为coord_cartesian强制裁剪了绘图范围,但stat_density_2d生成的多边形是基于整个数据集的密度估计范围绘制的,超出coord_cartesian设定的区域就会被直接截断。这里有两种可行的解决方法:

方法一:让密度估计范围适配绘图边界

手动指定stat_density_2d的密度估计范围,和你coord_cartesian设定的范围保持一致,这样生成的多边形就不会超出裁剪区域:

ggplot(data=test_data,aes(x = X206.204 , y = X207.204))+
  stat_density_2d(geom="polygon",n=800,bins=20, 
                  aes(fill = ..level.., alpha = ..level..),
                  # 手动对齐密度估计范围与绘图边界
                  xlim = c(17,19.6), ylim = c(15.4, 15.9)) +
  geom_point(color="red")+
  labs( x = expression({}^206*"Pb/"*{}^204*"Pb"), y = expression({}^207*"Pb/"*{}^204*"Pb") )+
  theme_bw() +
  theme(panel.grid = element_blank(), 
        axis.text.x = element_text(margin = margin(t = 5, unit = "pt")),
        axis.text=element_text(size=18),
        axis.title = element_text(size=22),
        legend.position="none")+
  scale_fill_gradient(low = "cyan1",high = "cyan4")+
  scale_x_continuous(breaks = seq(17, 19.6, by = 0.2))+
  scale_y_continuous(breaks = seq(15.4, 15.9, by = 0.1))+
  coord_cartesian(xlim = c(17,19.6),ylim=c(15.4, 15.9))

方法二:用scale_x/y_continuous替代coord_cartesian

coord_cartesian是硬裁剪(先绘图再切边界),而scale_x/y_continuous的limits参数是先过滤数据再计算密度,生成的多边形自然不会超出绘图范围:

ggplot(data=test_data,aes(x = X206.204 , y = X207.204))+
  stat_density_2d(geom="polygon",n=800,bins=20, 
                  aes(fill = ..level.., alpha = ..level..)) +
  geom_point(color="red")+
  labs( x = expression({}^206*"Pb/"*{}^204*"Pb"), y = expression({}^207*"Pb/"*{}^204*"Pb") )+
  theme_bw() +
  theme(panel.grid = element_blank(), 
        axis.text.x = element_text(margin = margin(t = 5, unit = "pt")),
        axis.text=element_text(size=18),
        axis.title = element_text(size=22),
        legend.position="none")+
  scale_fill_gradient(low = "cyan1",high = "cyan4")+
  # 用limits参数替代coord_cartesian的硬裁剪
  scale_x_continuous(breaks = seq(17, 19.6, by = 0.2), limits = c(17,19.6))+
  scale_y_continuous(breaks = seq(15.4, 15.9, by = 0.1), limits = c(15.4, 15.9))

2. 中间大片无数据区域问题

观察你的数据分布,能明显看到几个独立的聚类(比如x≈17、x≈17.9、x≈18.3-18.7的分组),这些分组之间确实没有数据点,所以密度估计在中间区域的概率极低,空白是正常现象。如果想让填充视觉上更连贯,可以尝试:

  • 减少bins数量,比如把bins=20改成bins=10,扩大等高线间隔,减少空白区域的占比;
  • 改用geom="contour_filled"(ggplot2 3.3.0及以上版本支持),它的填充逻辑更适配多峰数据,能避免多边形拼接的缝隙:
ggplot(data=test_data,aes(x = X206.204 , y = X207.204))+
  stat_density_2d(geom="contour_filled",n=800,bins=15, 
                  aes(fill = ..level..)) +
  geom_point(color="red")+
  labs( x = expression({}^206*"Pb/"*{}^204*"Pb"), y = expression({}^207*"Pb/"*{}^204*"Pb") )+
  theme_bw() +
  theme(panel.grid = element_blank(), 
        axis.text.x = element_text(margin = margin(t = 5, unit = "pt")),
        axis.text=element_text(size=18),
        axis.title = element_text(size=22),
        legend.position="none")+
  scale_fill_gradient(low = "cyan1",high = "cyan4")+
  scale_x_continuous(breaks = seq(17, 19.6, by = 0.2), limits = c(17,19.6))+
  scale_y_continuous(breaks = seq(15.4, 15.9, by = 0.1), limits = c(15.4, 15.9))

你也可以先跑下面的代码确认数据的真实分布,就能更直观理解中间空白的原因:

ggplot(test_data, aes(X206.204, X207.204)) + geom_point(color="red")

内容的提问来源于stack exchange,提问作者Gary Hsu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:25:41