我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?

huangapple go评论131阅读模式
英文:

How can I color the border line differently between two points on a map made with geom_sf and ggplot2?

问题

最近,我在这里发布了一个类似的问题,我收到了以下答案,

library(sf)
library(ggplot2)

nc <- st_read(system.file("shape/nc.shp", package="sf"))

rect <- list(matrix(
    c(-85, 35.5, 
      -80, 35.5, 
      -80, 36.5, 
      -85, 36.5, 
      -85, 35.5),
    byrow = TRUE, 
    ncol = 2
  )) |>
  st_polygon() |>
  st_sfc(crs = st_crs(nc))

border_line <- st_intersection(
  rect, 
  st_cast(st_union(nc), "MULTILINESTRING")
)

ggplot(nc) +
  geom_sf() +
  geom_sf(data = border_line, color = "red")

产生了这张地图:

我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?

当时它运行良好。然而,我最近一直在寻找更加优雅的解决方案,因为上述答案可能有点麻烦,特别是在处理具有冲突纬度和经度的边界线时,附图的东北地区可以作为这种情况的示例。因此,我欢迎您的建议,并提前感谢您的关注。

英文:

Recently, I have posted a similar question here and I received the following answer,

library(sf)
library(ggplot2)

nc <- st_read(system.file("shape/nc.shp", package="sf"))

rect <- list(matrix(
    c(-85, 35.5, 
      -80, 35.5, 
      -80, 36.5, 
      -85, 36.5, 
      -85, 35.5),
    byrow = TRUE, 
    ncol = 2
  )) |>
  st_polygon() |>
  st_sfc(crs = st_crs(nc))

border_line <- st_intersection(
  rect, 
  st_cast(st_union(nc), "MULTILINESTRING")
)

ggplot(nc) +
  geom_sf() +
  geom_sf(data = border_line, color = "red")

which produced this map:

我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?

and it worked well at that time. However, I have recently been searching for a more elegant solution to this problem, as the aforementioned answer can be somewhat troublesome, especially when dealing with border lines that have conflicting latitudes and longitudes, which the northeast region of the attached map can be an example for this case. Therefore, I do welcome your suggestions and thank you in advance for your attention.

答案1

得分: 1

以下是翻译好的部分:

首先为您定义要着色的部分的近似起始和结束坐标:

start <- c(-85, 35.5) |>
  st_point() |>
  st_sfc(crs = st_crs(nc))

stop <- c(-81.8, 36.6) |>
  st_point() |>
  st_sfc(crs = st_crs(nc))

现在将整个边界作为点的集合,并找到最接近您选择的起始点和结束点的点:

border_points <- st_cast(st_union(nc), "POINT")

start <- which.min(st_distance(start, border_points))
stop <- which.min(st_distance(stop, border_points))

现在从起始和结束标记之间提取边界点,并将它们转换为单个线串:

border_line <- border_points[start:stop] |>
  st_coordinates() |>
  st_linestring() |>
  st_sfc(crs = st_crs(nc))

然后可以像以前一样绘图:

ggplot(nc) +
  geom_sf() +
  geom_sf(data = border_line, color = "red")

这应该比边界框方法更好地处理不规则海岸线。例如,可以如下标记nc地图的东部:

stop <- c(-76, 36.4) |>
  st_point() |>
  st_sfc(crs = st_crs(nc))

start <- c(-78, 34) |>
  st_point() |>
  st_sfc(crs = st_crs(nc))

border_points <- st_cast(st_union(nc), "POINT")

start <- which.min(st_distance(start, border_points))
stop <- which.min(st_distance(stop, border_points))

border_line <- border_points[start:stop] |>
  st_coordinates() |>
  st_linestring() |>
  st_sfc(crs = st_crs(nc))

ggplot(nc) +
  geom_sf() +
  geom_sf(data = border_line, color = "red")

我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?
我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?

英文:

Something like this may work for you. First define approximate start and end co-ordinates of the section you want to colour:

start &lt;- c(-85, 35.5) |&gt;
  st_point() |&gt;
  st_sfc(crs = st_crs(nc))

stop &lt;- c(-81.8, 36.6) |&gt;
  st_point() |&gt;
  st_sfc(crs = st_crs(nc))

Now get the whole border as a collection of points, and find which points are nearest to your chosen start and end points:

border_points &lt;- st_cast(st_union(nc), &quot;POINT&quot;)

start &lt;- which.min(st_distance(start, border_points))
stop &lt;- which.min(st_distance(stop, border_points))

Now subset the border points between the start and end markers, and convert them into a single linestring:

border_line &lt;- border_points[start:stop] |&gt;
  st_coordinates() |&gt;
  st_linestring() |&gt;
  st_sfc(crs = st_crs(nc))

You can then plot as before:

ggplot(nc) +
  geom_sf() +
  geom_sf(data = border_line, color = &quot;red&quot;)

我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?

This should handle irregular coastlines a bit better than the bbox method. For example, the East of the nc map could be marked as follows:

stop &lt;- c(-76, 36.4) |&gt;
  st_point() |&gt;
  st_sfc(crs = st_crs(nc))

start &lt;- c(-78, 34) |&gt;
  st_point() |&gt;
  st_sfc(crs = st_crs(nc))

border_points &lt;- st_cast(st_union(nc), &quot;POINT&quot;)

start &lt;- which.min(st_distance(start, border_points))
stop &lt;- which.min(st_distance(stop, border_points))

border_line &lt;- border_points[start:stop] |&gt;
  st_coordinates() |&gt;
  st_linestring() |&gt;
  st_sfc(crs = st_crs(nc))

ggplot(nc) +
  geom_sf() +
  geom_sf(data = border_line, color = &quot;red&quot;)

我如何在使用geom_sf和ggplot2制作的地图上将两个点之间的边框线颜色不同?

huangapple
  • 本文由 发表于 2023年6月13日 05:07:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76460342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定