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

geom_hex与geom_bin_2d分箱绘图结果冲突的原因及标准化方案

关于geom_hex与geom_bin_2d分箱绘图差异的问题与解决方法

我尝试用geom_hex和geom_bin_2d的分箱功能解决绘图过度叠加问题,但两者输出的计数显示差异极大。虽然知道分箱逻辑不同,但想明白差异为何这么显著,以及如何让两者生成可对比的标准化结果,避免解读混乱。

差异显著的核心原因

1. 分箱形状与点归属逻辑完全不同

  • geom_bin_2d采用轴对齐的正方形网格,每个分箱是严格的矩形,数据点只会落入一个正方形单元,统计逻辑是矩形区域内的点计数。
  • geom_hex采用交错排列的六边形网格,相邻行的六边形偏移半个边长,点的归属是基于六边形的覆盖区域,和正方形分箱的统计单元完全不重合,同一组点在两种规则下的计数自然差异明显。

2. bins参数的定义不一致

  • 对geom_bin_2d,bins是x轴和y轴各自的分箱数量,比如bins=40意味着x轴40个分箱、y轴40个分箱,总共有1600个正方形单元。
  • 对geom_hex,bins仅指x轴方向的六边形数量,y轴的六边形数量会根据坐标轴比例自动调整,总单元数更少,且每个六边形的面积和正方形分箱的面积不相等,统计粒度不一致进一步放大了计数差异。

标准化绘图结果的方法

1. 用binwidth替代bins统一统计粒度

不要依赖模糊的bins参数,直接用binwidth指定分箱的实际尺寸:

  • 对geom_bin_2d,用binwidth=c(x_width, y_width)定义正方形的宽和高。
  • 对geom_hex,为了让六边形面积和正方形分箱接近,设置binwidth=c(x_width, y_width * sqrt(3)/2)(六边形垂直高度与水平宽度的比例为√3/2≈0.866)。

2. 强制统一颜色标尺

确保两者使用完全相同的填充色设置:包括limits(计数范围)、breaks(刻度断点)、palette(颜色方案),这样颜色对应的计数区间完全一致,避免视觉上的误导。

3. 可选:手动对齐分箱原点

geom_bin_2d可通过origin参数指定分箱起始点;geom_hex虽无直接参数,但可通过偏移数据坐标让六边形网格与正方形网格对齐,此操作仅在需要严格对齐统计单元时使用。


示例验证

示例1:钻石数据集对比

library(ggplot2)
# 定义统一的颜色标尺
bks = seq(from = 0, to = 10000, by = 1000)
fill_scale <- scale_fill_distiller(palette = "Spectral", breaks = bks, limits = c(0, 6000))

d <- ggplot(diamonds, aes(carat, price))
# 基础散点图
d + geom_point(alpha = 0.01)

散点图

# 用统一binwidth绘制对比图
bw <- c(0.1, 500)
# geom_bin_2d版本
d + geom_bin_2d(binwidth = bw) + fill_scale
# geom_hex版本(匹配面积)
d + geom_hex(binwidth = c(bw[1], bw[2] * sqrt(3)/2)) + fill_scale

分箱对比图1
分箱对比图2

示例2:物种分布数据集对比

library(sf)
library(ggplot2)
library(rgbif)
library(maps)

# 获取GBIF物种数据
gdata <- occ_data(scientificName = "Aix sponsa", country = "US", 
                  year="2020", limit = 5000)
gdata <- gdata$data

# 准备美国地图
usa <- sf::st_as_sf(map('usa', plot = FALSE, fill = TRUE))
usa <- sf::st_transform(usa, sp::CRS("+init=epsg:4326"))

# 转换物种数据为SF格式
gdata_sf <- st_as_sf(gdata, coords = c('decimalLongitude', 'decimalLatitude'),
                     crs = st_crs(usa))

# 基础散点图
ggplot(usa) +
  geom_sf() +
  geom_sf(data = gdata_sf, alpha = 0.1)

物种分布散点图

# 统一颜色标尺和分箱参数
bks = seq(from = 0, to = 200, by = 50)
fill_scale <- scale_fill_distiller(palette = "Spectral", limits = c(0, 200), breaks = bks)
bw <- c(0.5, 0.5)

# geom_bin_2d绘图
ggplot(usa) +
  geom_sf() +
  geom_bin_2d(data = gdata, aes(x = decimalLongitude, y = decimalLatitude,
                                fill = after_stat(count)),
              alpha = 0.8, colour = "white", binwidth = bw) +
  fill_scale +
  geom_sf(data = gdata_sf, alpha = 0.1) + 
  theme_void()

# geom_hex绘图(匹配面积)
ggplot(usa) +
  geom_sf() +
  geom_hex(data = gdata, aes(x = decimalLongitude, y = decimalLatitude,
                             fill = after_stat(count)),
           alpha = 0.8, colour = "white", binwidth = c(bw[1], bw[2] * sqrt(3)/2)) +
  fill_scale +
  geom_sf(data = gdata_sf, alpha = 0.1) +
  theme_void()

物种分布分箱对比图


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:10:32