如何在R的grid包中获取不规则polygon grob的准确外尺寸?
如何获取grid包中不规则polygon grob的准确外尺寸?
我尝试使用R语言grid包的grobX()和grobY()函数,为polygonGrob()绘制的多边形添加边界框。对于矩形这类规则形状,能正确获取外尺寸,但不规则多边形的结果存在偏差。
原始代码与问题复现
首先定义多边形数据和grob对象:
x <- c(0.65, 0.614906666467847, 0.42604722665004, 0.425, 0.359046106882114, 0.259046106882114, 0.425, 0.526047226650039, 0.614906666467847) y <- c(0.5, 0.692836282905962, 0.895442325903662, 0.759807621135332, 0.602606042997701, 0.397393957002299, 0.240192378864668, 0.204557674096338, 0.307163717094038) library(grid) pg <- polygonGrob(x=x, y=y, default.units = "native", gp=gpar(fill="gray")) pntg <- pointsGrob(x=x, y=y, pch = 20, size = grid::unit(3, "mm"), default.units = "native", gp=gpar(col="red")) rcg <- rectGrob(x=0.33, height=0.7, width=0.2, gp=gpar(fill="gray"))
不规则多边形的错误边界框
使用grobX()/grobY()绘制边界框时,结果无法准确覆盖多边形:
pushViewport(plotViewport(c(5, 4, 2, 2))) pushViewport(dataViewport(x, y)) grid.rect() grid.xaxis() grid.yaxis() grid.draw(pg) grid.draw(pntg) x1 <- grid::convertWidth(grid::grobX(pg, "west"), "npc", TRUE) x2 <- grid::convertWidth(grid::grobX(pg, "east"), "npc", TRUE) y1 <- grid::convertHeight(grid::grobY(pg, "south"), "npc", TRUE) y2 <- grid::convertHeight(grid::grobY(pg, "north"), "npc", TRUE) grid::grid.polyline(x = c(x1, x1, x2, x2, x1), y = c(y1, y2, y2, y1, y1), default.units = "npc", gp = gpar(col = "blue"))

矩形的正确边界框
同样方法对矩形rectGrob()有效:
pushViewport(plotViewport(c(5, 4, 2, 2))) pushViewport(dataViewport(x, y)) grid.rect() grid.xaxis() grid.yaxis() grid.draw(rcg) x1 <- grid::convertWidth(grid::grobX(rcg, "west"), "npc", TRUE) x2 <- grid::convertWidth(grid::grobX(rcg, "east"), "npc", TRUE) y1 <- grid::convertHeight(grid::grobY(rcg, "south"), "npc", TRUE) y2 <- grid::convertHeight(grid::grobY(rcg, "north"), "npc", TRUE) grid::grid.polyline(x = c(x1, x1, x2, x2, x1), y = c(y1, y2, y2, y1, y1), gp = gpar(col = "red"))

解决方法
grobX()/grobY()对polygonGrob()使用"west"/"east"/"north"/"south"参数时,并非返回多边形顶点的实际极值,而是基于grob的对齐参考点计算,因此会出现偏差。正确做法是直接提取多边形顶点坐标,计算极值后转换单位绘制边界框:
pushViewport(plotViewport(c(5, 4, 2, 2))) pushViewport(dataViewport(x, y)) grid.rect() grid.xaxis() grid.yaxis() grid.draw(pg) grid.draw(pntg) # 提取多边形顶点的native单位数值 pg_x <- convertUnit(pg$x, "native", valueOnly = TRUE) pg_y <- convertUnit(pg$y, "native", valueOnly = TRUE) # 计算坐标极值 x_min <- min(pg_x) x_max <- max(pg_x) y_min <- min(pg_y) y_max <- max(pg_y) # 将极值转换为npc单位 x1 <- convertX(unit(x_min, "native"), "npc", valueOnly = TRUE) x2 <- convertX(unit(x_max, "native"), "npc", valueOnly = TRUE) y1 <- convertY(unit(y_min, "native"), "npc", valueOnly = TRUE) y2 <- convertY(unit(y_max, "native"), "npc", valueOnly = TRUE) # 绘制准确边界框 grid.polyline(x = c(x1, x1, x2, x2, x1), y = c(y1, y2, y2, y1, y1), default.units = "npc", gp = gpar(col = "blue"))
这种方法直接基于多边形原始顶点计算边界框,能准确覆盖所有顶点,解决grobX()/grobY()的偏差问题。
内容的提问来源于stack exchange,提问作者Crops
相关产品推荐
相关产品推荐

