Tje*_*ebo 8 r polygon ggplot2 r-sp r-sf
这是改进居中县名称 ggplot 和地图以及地图上 ggplot 居中名称的扩展。这不仅仅是一个理论问题,我在回答How merge certain states Together by group with one label in ggplot2 in R? 时遇到了这种特殊情况。。在这里,我发现有一个L形的“网格”通向多边形外部的中点位置。另请参阅 Henrik 的链接线程Calculate Centroid Within / INSIDE a SpatialPolygon。。
我想知道是否有办法强制标签进入多边形,以获得“更直观”的中点。“直观地”可能意味着“多边形内距离任何边界最远的点”(相关线程的答案建议使用一个函数来计算它,但这个函数似乎没有给出与rgeos::gCentroid我的示例中不同的结果)。
任何建议都应该是完全自动化的,理想情况下适用于任何(ir-)正多边形,并且也独立于坐标投影(即坐标纵横比不重要) 校正:理想情况下它应该取决于坐标投影,因为这可能会将文本移动到边框的尴尬位置。因此,理想的解决方案可能应该在绘制时计算标签位置。
非常相关的是https://gis.stackexchange.com/questions/29278/finding-point-in-country-furthest-from-boundary和https://mathoverflow.net/questions/161494/get-a-point- in-polygon-maximize-the-distance-from-borders,但我不知道如何在 R / grid / ggplot2 中实现这一点。
suppressMessages({library(ggh4x)
library(sf)
library(dplyr)
library(patchwork)
})
poly_foo <- data.frame(x = c(0:1, rep(2,4), rep(1.5,3), 0), y = c(rep(0,3), 1:3, 3:1, 1))
p <- ggplot(poly_foo, aes(x, y) ) +
geom_polygon(color = "black", fill = NA)
p1 <- p +
stat_midpoint(aes(label = "ggh4x::stat_midpoint\nNot ideal"), geom = "text")
## Convert to simple feature object for geom_sf
point_sf <- st_as_sf(poly_foo, coords = c("x", "y"))
poly_sf <-
point_sf %>%
summarise(geometry = st_combine(geometry)) %>%
st_cast("POLYGON") %>%
mutate(label = "sf::st_point_on_surface\nNot ideal")
p2 <- ggplot(poly_sf) +
geom_sf() +
geom_sf_text(aes(label = label))
## convert to spatial object (sp) for rgeos::gCentroid
xy_lab <- rgeos::gCentroid(as_Spatial(poly_sf))@coords
p3 <- ggplot(poly_sf) +
geom_sf() +
annotate(geom = "text", label = "rgeos::gCentroid\nNot ideal",
x = xy_lab[1], y = xy_lab[2])
p4 <- p +
annotate(geom = "text", x = 1.7, y = .5, label = "more\nintuitive\n\'midpoint\'")
## it should ideally change with different coordinates
p5 <- p + coord_fixed() +
annotate(geom = "text", x = 1, y = .5, label = "more\nintuitive\n\'midpoint\'\ncoordinates changed")
p1 + p2 + p3 + plot_annotation(title = "Example problem")
Run Code Online (Sandbox Code Playgroud)

## Desired output
p4 + p5 + plot_annotation(title = "Desired behaviour")
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v2.0.1)于 2022-06-26 创建
使用您所掌握的信息以及@Henrik 提供的信息,效果非常好。
\n不过,有一个问题。ggplot文本到绘图的大小未统一缩放。您在查看器窗格中使用它吗?你要出口这个吗?您使用什么尺寸?例如,标题在 300 dpi 下的字体大小可能为 15,但如果您想添加相同大小的文本,则必须将大小设置为15/.pt(其中.pt是来自包的静态值ggplot2)。
此外,默认字体类型ggplot不是等宽\xe2\x80\x94,每个字母都不会获得相同数量的空间(例如,像 courier)。
查看这些以 300dpi、3 英寸 x 3 英寸保存的图,其中包含文本size = 12/.pt和coord_equal. 在第一个图中,“HHH”在 x 轴上仅占据 0.25 个单位。第二个需要 1.5 个单位。在最后一张图中,它只需要 1/2 单位多一点。
这有效。然而,如果没有设定的缩放机制,它仍然需要对字体大小或字符串换行进行手动干预。
\nlibrary(polylabelr)\nlibrary(stringr)\nlibrary(tidyverse)\n\npoly_foo <- data.frame(x = c(0:1, rep(2,4), rep(1.5,3), 0),\n y = c(rep(0,3), 1:3, 3:1, 1))\n\np <- ggplot(poly_foo, aes(x, y) ) +\n geom_polygon(color = "black", fill = NA)\nplr <- poi(poly_foo, precision, = .1)\np + \n coord_equal() +\n annotate("text", x = plr$x, y = plr$y, label = "How about here?" %>% \n str_wrap(., width = 9/(plr$dist * 2)))\n\npf2 <- mutate(poly_foo, x = x * 2, y = y^2)\npoi2 <- poi(pf2, precision = .1)\nggplot(pf2, aes(x, y) ) +\n geom_polygon(color = "black", fill = NA) + \n coord_equal() + \n annotate("text", x = poi2$x, y = poi2$y,\n label = "Intuitive enough?" %>% \n str_wrap(., width = 9/(poi2$dist * 2)))\n\npf3 <- mutate(poly_foo, x = x^2, y = y + 4)\npoi3 <- poi(pf3, precision = .1)\nggplot(pf3, aes(x, y) ) +\n geom_polygon(color = "black", fill = NA) + \n coord_equal() + \n annotate("text", x = poi3$x, y = poi3$y, \n label = "Intuitive enough?" %>% \n str_wrap(., width = 9/(poi3$dist * 2)))\n\npf4 <- mutate(poly_foo, x = x^1/2, y = y^(1/3))\npoi4 <- poi(pf4, precision = .1)\nggplot(pf4, aes(x, y) ) +\n geom_polygon(color = "black", fill = NA) + \n coord_fixed() + \n annotate("text", x = poi4$x, y = poi4$y,\n label = "Intuitive enough?" %>% \n str_wrap(., width = 9/(poi4$dist * 2)))\nRun Code Online (Sandbox Code Playgroud)\n\n
| 归档时间: |
|
| 查看次数: |
976 次 |
| 最近记录: |