ggplot叠加imager图像拉伸、热图及散点偏移问题求助
在人体模板上正确绘制热图的解决方案
我明白你现在遇到的问题——图像拉伸、散点和热图偏离人体模板的预期位置,这其实是ggplot的坐标系统和图像的坐标系统不匹配导致的,咱们一步步来解决:
一、解决图像拉伸问题
ggplot的coord_fixed()默认是1:1的比例,但你的人体图像肯定不是正方形,所以必须用图像的原始宽高比来固定坐标比例:
- 先获取图像的宽和高:
img_width <- dim(traf)[2],img_height <- dim(traf)[1] - 计算宽高比:
img_aspect_ratio <- img_width / img_height - 把
coord_fixed()的ratio参数设为这个值,就能让绘图区域和图像原始尺寸完全匹配,不会再拉伸。
二、修正热图与散点的偏移问题
偏移的核心原因是图像的y轴方向和ggplot默认的y轴方向相反:图像加载后,y=0是顶部,而ggplot默认y=0是底部,所以咱们要反转y轴来对齐:
- 在
scale_y_continuous()里加上trans = "reverse",让y轴方向和图像一致 - 同时把y轴的
limits改成c(img_height, 0),这样数据的y值就能精准对应图像的垂直位置 - 把
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
相关产品推荐
相关产品推荐

