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

如何在ggplot2热图中硬编码分箱位置匹配指定9个矩形

在ggplot2投球热图中手动指定分箱位置匹配geom_rect并过滤外部数据

核心思路

自动分箱(依赖binwidth)只会基于数据范围均匀划分,无法精准对齐预设的9个矩形。解决核心是硬编码分箱边界,强制将数据划入对应区间,同时过滤矩形外的数据,再基于自定义分箱完成绘图。

具体实现步骤

1. 定义9个矩形的分箱边界

先根据你预设的geom_rect位置,硬编码x轴(投球横向位置)和y轴(纵向位置)的分箱边界(3x3矩形需要4个边界值来划分3个区间):

# 请根据你的实际矩形位置修改这些数值
x_breaks <- c(-2, -0.5, 0.5, 2)  # x轴4个边界,分出3个横向区间
y_breaks <- c(0, 1.5, 3, 4.5)   # y轴4个边界,分出3个纵向区间

2. 处理数据:分箱+过滤外部数据

用cut()给数据分配分箱,同时过滤掉不在矩形范围内的数据:

library(dplyr)
library(ggplot2)

# 读取你的投球数据(替换为你的数据读取方式)
pitch_data <- read.csv("你的数据文件路径")

# 分箱并过滤无效数据
processed_data <- pitch_data %>%
  # 给x、y变量分配对应分箱,include.lowest确保边界值被纳入
  mutate(
    x_bin = cut(x, breaks = x_breaks, include.lowest = TRUE),
    y_bin = cut(y, breaks = y_breaks, include.lowest = TRUE)
  ) %>%
  # 过滤掉矩形外的无分箱数据
  filter(!is.na(x_bin), !is.na(y_bin)) %>%
  # 统计每个分箱的投球数(或你需要的其他指标)
  count(x_bin, y_bin, name = "pitch_count") %>%
  # 计算分箱中心坐标,用于热图定位
  mutate(
    x_center = (as.numeric(sub("\\((.*),.*\\]", "\\1", x_bin)) + 
                as.numeric(sub(".*,(.*)\\]", "\\1", x_bin))) / 2,
    y_center = (as.numeric(sub("\\((.*),.*\\]", "\\1", y_bin)) + 
                as.numeric(sub(".*,(.*)\\]", "\\1", y_bin))) / 2
  )

3. 绘图:对齐矩形与热图

用geom_rect画出预设的9个矩形,再用geom_tile展示分箱统计结果:

ggplot() +
  # 绘制9个基准矩形
  geom_rect(
    data = expand.grid(x_start = x_breaks[-4], x_end = x_breaks[-1],
                      y_start = y_breaks[-4], y_end = y_breaks[-1]),
    aes(xmin = x_start, xmax = x_end, ymin = y_start, ymax = y_end),
    fill = "transparent", color = "black", size = 1
  ) +
  # 绘制投球热图
  geom_tile(data = processed_data,
            aes(x = x_center, y = y_center, fill = pitch_count),
            width = diff(x_breaks)[1], height = diff(y_breaks)[1]) +
  # 可选:添加分箱投球数标签
  geom_text(data = processed_data,
            aes(x = x_center, y = y_center, label = pitch_count)) +
  # 对齐坐标轴刻度与分箱边界
  scale_x_continuous(breaks = x_breaks) +
  scale_y_continuous(breaks = y_breaks) +
  theme_minimal()

替代方案:直接用stat_bin2d指定breaks

如果不想提前聚合数据,可直接在stat_bin2d中指定分箱边界,并用坐标轴范围过滤外部数据:

ggplot(pitch_data, aes(x = x, y = y)) +
  geom_rect(
    data = expand.grid(x_start = x_breaks[-4], x_end = x_breaks[-1],
                      y_start = y_breaks[-4], y_end = y_breaks[-1]),
    aes(xmin = x_start, xmax = x_end, ymin = y_start, ymax = y_end),
    inherit.aes = FALSE, fill = "transparent", color = "black", size = 1
  ) +
  # 指定分箱边界,自动统计每个箱子的投球数
  stat_bin2d(breaks = list(x = x_breaks, y = y_breaks),
             aes(fill = after_stat(count))) +
  # 过滤矩形外的数据
  xlim(range(x_breaks)) +
  ylim(range(y_breaks)) +
  theme_minimal()

关键注意事项

  • 必须保证x_breaks和y_breaks的数值与geom_rect的矩形边界完全一致,否则分箱会错位。
  • 若矩形不是等宽等高,需手动调整geom_tile的width和height参数,匹配每个箱子的实际尺寸。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:30:35