如何结合ggplot高亮与hextri的六边形分箱类别比例展示?
解决方案
要同时实现分箱内分组占比的三角形展示和目标分箱高亮,我们可以绕过hextri的独立绘图逻辑,手动计算hex分箱的统计信息,完全用ggplot2实现需求,自然融合两种效果:
步骤说明
- 使用
hexbin包计算分箱,获取每个分箱的位置、分组计数 - 推导分箱内的分组占比,生成用于绘制三角形的坐标数据
- 用
ggplot2绘制三角形实现占比展示,叠加高亮边框
完整代码
library(ggplot2) library(hexbin) n = 100 df = data.frame(x = rnorm(n), y = rnorm(n), group = sample(0:1, n, prob = c(0.9, 0.1), replace = TRUE)) # 1. 计算hex分箱的基础统计信息 hb <- hexbin(df$x, df$y, xbins = 3) # 统计每个分箱中group=0和group=1的数量 bin_counts <- aggregate(group ~ hb@cell, data = df, FUN = function(x) c(sum(x==0), sum(x==1))) bin_counts <- cbind(hb@xcm, hb@ycm, bin_counts$group) colnames(bin_counts) <- c("x", "y", "count0", "count1") # 计算占比和是否需要高亮(存在group=1则高亮) bin_counts <- as.data.frame(bin_counts) %>% mutate(total = count0 + count1, prop1 = count1 / total, highlight = ifelse(count1 > 0, TRUE, FALSE)) # 2. 生成绘制三角形的坐标数据 # hex的顶点偏移量(基于hexbin的单位) hex_radius <- hb@xbins / diff(range(df$x)) * 0.5 hex_offsets <- data.frame( dx = hex_radius * c(0, 0.866, 0.866, 0, -0.866, -0.866), dy = hex_radius * c(1, 0.5, -0.5, -1, -0.5, 0.5) ) # 为每个分箱生成两个三角形的坐标(对应group0和group1的占比) plot_data <- lapply(1:nrow(bin_counts), function(i) { row <- bin_counts[i,] # 分箱中心 cx <- row$x cy <- row$y # 根据group1的占比调整分割线位置 split_y <- cy - row$prop1 * 2 * hex_radius # group1的三角形(上半部分) tri1 <- data.frame( x = c(cx, cx + hex_offsets$dx[2], cx + hex_offsets$dx[3]), y = c(cy, cy + hex_offsets$dy[2], split_y), group = "1", highlight = row$highlight, bin_x = cx, bin_y = cy ) # group0的三角形(下半部分) tri0 <- data.frame( x = c(cx, cx + hex_offsets$dx[5], cx + hex_offsets$dx[6]), y = c(split_y, cy + hex_offsets$dy[5], cy + hex_offsets$dy[6]), group = "0", highlight = row$highlight, bin_x = cx, bin_y = cy ) rbind(tri1, tri0) }) %>% bind_rows() # 3. 用ggplot绘制最终图表 ggplot() + # 绘制分组三角形 geom_polygon(data = plot_data, aes(x = x, y = y, fill = group, group = interaction(bin_x, bin_y, group)), color = "black") + # 绘制高亮边框(仅针对有group1的分箱) geom_polygon(data = filter(bin_counts, highlight), aes(x = x + dx, y = y + dy, group = 1), data = hex_offsets, inherit.aes = FALSE, fill = NA, color = "yellow", size = 1.5) + # 设置颜色匹配原hextri scale_fill_manual(values = c("0" = "#00b38a", "1" = "#ea324c"), guide = "none") + theme_minimal()
关键说明
- 通过
hexbin直接获取分箱的中心位置和分组计数,避免hextri的黑箱绘图逻辑,方便和ggplot2图层系统结合 - 手动生成三角形坐标模拟
hextri的占比展示效果,同时可自由控制分箱的高亮边框 - 高亮逻辑和原
ggplot代码一致:只要分箱内存在group=1的点,就添加黄色边框
内容的提问来源于stack exchange,提问作者SamPassmore
相关产品推荐
相关产品推荐

