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

ggplot叠加imager图像拉伸、热图及散点偏移问题求助

在人体模板上正确绘制热图的解决方案

我明白你现在遇到的问题——图像拉伸、散点和热图偏离人体模板的预期位置,这其实是ggplot的坐标系统和图像的坐标系统不匹配导致的,咱们一步步来解决:

一、解决图像拉伸问题

ggplot的coord_fixed()默认是1:1的比例,但你的人体图像肯定不是正方形,所以必须用图像的原始宽高比来固定坐标比例:

  1. 先获取图像的宽和高:img_width <- dim(traf)[2],img_height <- dim(traf)[1]
  2. 计算宽高比:img_aspect_ratio <- img_width / img_height
  3. 把coord_fixed()的ratio参数设为这个值,就能让绘图区域和图像原始尺寸完全匹配,不会再拉伸。

二、修正热图与散点的偏移问题

偏移的核心原因是图像的y轴方向和ggplot默认的y轴方向相反:图像加载后,y=0是顶部,而ggplot默认y=0是底部,所以咱们要反转y轴来对齐:

  1. 在scale_y_continuous()里加上trans = "reverse",让y轴方向和图像一致
  2. 同时把y轴的limits改成c(img_height, 0),这样数据的y值就能精准对应图像的垂直位置
  3. 把annotation_raster的x/y范围从-Inf/Inf改成图像的实际宽高(0到img_width,0到img_height),确保图像完全填充绘图区域,不会错位。

修正后的完整代码

library(ggplot2)
library(imager) # 假设你用的是imager包的load.image

# 加载人体模板图像
traf <- load.image("50perc.jpg")
img_width <- dim(traf)[2]
img_height <- dim(traf)[1]
img_aspect_ratio <- img_width / img_height

# 你的数据框
df <- structure(list(w = c("A", "B", "C", "D", "E" ), 
                     f1 = c(129, 111, 128, 129, 126), 
                     f2 = c(55, 133, 55, 127, 56)), 
                row.names = c(46L, 111L, 113L, 115L, 118L), 
                class = "data.frame")

# 绘制对齐的热图+散点
ggplot(df, aes(x = f1, y = f2)) +
  # 精准对齐人体模板图像
  annotation_raster(traf, xmin = 0, xmax = img_width, ymin = 0, ymax = img_height) +
  # 绘制2D密度热图,加alpha避免遮挡图像
  stat_density2d(geom = "polygon", aes(fill = ..level..), alpha = 0.5) +
  # 绘制散点
  geom_point(size = 0.5, color = "black") +
  # 设置热图颜色渐变
  scale_fill_gradient(low = "green", high = "red") +
  # x轴匹配图像宽度,无留白
  scale_x_continuous(limits = c(0, img_width), expand = c(0, 0)) +
  # y轴反转+匹配图像高度,无留白
  scale_y_continuous(limits = c(img_height, 0), expand = c(0, 0), trans = "reverse") +
  # 固定图像原始宽高比
  coord_fixed(ratio = img_aspect_ratio) +
  # 清理主题元素,让焦点在图像和数据上
  theme_minimal() +
  theme(axis.title = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank())

额外说明

  • 我给热图加了alpha = 0.5,这样能透过热图看到下方的人体模板,方便你确认散点和热图是否在预期的面部、颈部等区域。
  • 如果你的load.image来自其他包(比如png),只需要保证dim(traf)能正确返回图像的高、宽、通道数即可,代码逻辑不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:02:52