R – 绘图中线交点的坐标

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

R - Coordinates of lines intersections in a plot

问题

以下是您要翻译的内容:

数据的结构如下:

  1. df1 <- structure(list(V2 = 1:10, V1 = c(1.4, 1.5, 1.9, 4.5, 6.7, 7.8,
  2. 8.1, 8.2, 8.3, 8.9)), class = "data.frame", row.names = c(NA, -10L))
  3. df2 <- structure(list(V2 = 1:10, V1 = c(1.43390152077191, 2.30610947613604,
  4. 2.23775280718692, 5.41628585802391, 7.05710641788319, 8.77536501311697,
  5. 8.48437852263451, 8.68867353517562, 8.7907762312796, 8.91225462416187
  6. )), row.names = c(NA, -10L), class = "data.frame")
  7. df3 <- structure(list(V2 = 1:10, V1 = c(2.04147320063785, 2.01257497165352,
  8. 2.22035211822949, 5.08143315766938, 7.31734440829605, 8.23827453767881,
  9. 8.27036898061633, 8.91508049662225, 9.04778654868715, 9.74391470812261
  10. )), row.names = c(NA, -10L), class = "data.frame")

我创建了一个图表,得到了以下图片。

  1. dplyr::bind_rows(df1 = df1, df2 = df2, df3 = df3, .id = "id") %>%
  2. ggplot() + aes(V2, V1, color = id) +
  3. geom_line() +
  4. theme(legend.position = "bottom")

一些线条相交,但这些交点可能不在数据框中。是否可能找到交点的坐标?

英文:

The sructure of the
data is the following

  1. df1 &lt;- structure(list(V2 = 1:10, V1 = c(1.4, 1.5, 1.9, 4.5, 6.7, 7.8,
  2. 8.1, 8.2, 8.3, 8.9)), class = &quot;data.frame&quot;, row.names = c(NA, -10L))
  3. df2 &lt;- structure(list(V2 = 1:10, V1 = c(1.43390152077191, 2.30610947613604,
  4. 2.23775280718692, 5.41628585802391, 7.05710641788319, 8.77536501311697,
  5. 8.48437852263451, 8.68867353517562, 8.7907762312796, 8.91225462416187
  6. )), row.names = c(NA, -10L), class = &quot;data.frame&quot;)
  7. df3 &lt;- structure(list(V2 = 1:10, V1 = c(2.04147320063785, 2.01257497165352,
  8. 2.22035211822949, 5.08143315766938, 7.31734440829605, 8.23827453767881,
  9. 8.27036898061633, 8.91508049662225, 9.04778654868715, 9.74391470812261
  10. )), row.names = c(NA, -10L), class = &quot;data.frame&quot;)

I build a plot and receive the following image.

  1. dplyr::bind_rows(df1 = df1, df2 = df2, df3 = df3, .id = &quot;id&quot;) %&gt;%
  2. ggplot() + aes(V2, V1, color = id) +
  3. geom_line() +
  4. theme(legend.position = &quot;bottom&quot;)

R – 绘图中线交点的坐标

Some of the lines intersect, but those intersections are probably not in the dataframes. Is it possible to find out the coordinates of intersections?

答案1

得分: 2

以下是翻译好的部分:

你可以在将数据转换为 sf 对象并将其视为空间数据时找到坐标。

在你发布的代码上进行扩展:

  1. library(sf)
  2. df4 <- dplyr::bind_rows(df1 = df1, df2 = df2, df3 = df3, .id = "id")
  3. df4_sf <- df4 %>%
  4. st_as_sf(coords = c('V2', 'V1')) %>%
  5. group_by(id) %>%
  6. summarise(zz = 1) %>% ## 我不确定是否需要这一行。
  7. st_cast('LINESTRING')
  8. # > df4_sf
  9. # Simple feature collection with 3 features and 2 fields
  10. # geometry type: LINESTRING
  11. # dimension: XY
  12. # bbox: xmin: 1 ymin: 1.4 xmax: 10 ymax: 9.743915
  13. # epsg (SRID): NA
  14. # proj4string: NA
  15. # # A tibble: 3 x 3
  16. # id zz geometry
  17. # * <chr> <dbl> <LINESTRING>
  18. # 1 df1 1 (1 1.4, 2 1.5, 3 1.9, 4 4.5, 5 6.7, 6 7.8, 7 8.1, 8 8.2, 9 8.3, 10 8.9)
  19. # 2 df2 1 (1 1.433902, 2 2.306109, 3 2.237753, 4 5.416286, 5 7.057106, 6 8.775365, 7 8.484379, 8...
  20. # 3 df3 1 (1 2.041473, 2 2.012575, 3 2.220352, 4 5.081433, 5 7.317344, 6 8.238275, 7 8.270369, 8...

现在有三行,每一行代表原始的 df。

使用 geom_sf 绘制的图表显示仍然是相同的:

  1. ggplot(df4_sf) + geom_sf(aes(color = id)) + theme(legend.position = 'bottom')

R – 绘图中线交点的坐标

我们看到只有 2 和 3 交叉,所以我们将只看这两个。

  1. intersections <- st_intersections(df4_sf[2,], df4_sf[3,])
  2. st_coordinates(intersections)
  3. # X Y L1
  4. #[1,] 1.674251 2.021989 1
  5. #[2,] 4.562692 6.339562 1
  6. #[3,] 5.326387 7.617924 1
  7. #[4,] 7.485925 8.583651 1

最后,将所有内容绘制在一起:

  1. ggplot() +
  2. geom_sf(data = df4_sf, aes(color = id)) +
  3. geom_sf(data = intersections) +
  4. theme(legend.position = 'bottom')

给我们这个图:

R – 绘图中线交点的坐标

英文:

You can find the coordinates if you to make the data an sf object, and treat it as spatial data.

Adding on to the code you posted:

  1. library(sf)
  2. df4 &lt;- dplyr::bind_rows(df1 = df1, df2 = df2, df3 = df3, .id = &quot;id&quot;)
  3. df4_sf &lt;- df4 %&gt;%
  4. st_as_sf(coords = c(&#39;V2&#39;, &#39;V1&#39;)) %&gt;%
  5. group_by(id) %&gt;%
  6. summarise(zz = 1) %&gt;% ## I&#39;m not sure this line is needed.
  7. st_cast(&#39;LINESTRING&#39;)
  8. # &gt; df4_sf
  9. # Simple feature collection with 3 features and 2 fields
  10. # geometry type: LINESTRING
  11. # dimension: XY
  12. # bbox: xmin: 1 ymin: 1.4 xmax: 10 ymax: 9.743915
  13. # epsg (SRID): NA
  14. # proj4string: NA
  15. # # A tibble: 3 x 3
  16. # id zz geometry
  17. # * &lt;chr&gt; &lt;dbl&gt; &lt;LINESTRING&gt;
  18. # 1 df1 1 (1 1.4, 2 1.5, 3 1.9, 4 4.5, 5 6.7, 6 7.8, 7 8.1, 8 8.2, 9 8.3, 10 8.9)
  19. # 2 df2 1 (1 1.433902, 2 2.306109, 3 2.237753, 4 5.416286, 5 7.057106, 6 8.775365, 7 8.484379, 8...
  20. # 3 df3 1 (1 2.041473, 2 2.012575, 3 2.220352, 4 5.081433, 5 7.317344, 6 8.238275, 7 8.270369, 8...

Now there are three rows, each representing one of the original df's.

A plot using geom_sf showing that it's still the same:

  1. ggplot(df4_sf) + geom_sf(aes(color = id)) + theme(legend.position = &#39;bottom&#39;)

R – 绘图中线交点的坐标

We see that only 2 & 3 intersect, so we'll look at just those two.

  1. intersections &lt;- st_intersections(df4_sf[2,], df4_sf[3,])
  2. st_coordinates(intersections)
  3. # X Y L1
  4. #[1,] 1.674251 2.021989 1
  5. #[2,] 4.562692 6.339562 1
  6. #[3,] 5.326387 7.617924 1
  7. #[4,] 7.485925 8.583651 1

And finally plot everything together:

  1. ggplot() +
  2. geom_sf(data = df4_sf, aes(color = id)) +
  3. geom_sf(data = intersections) +
  4. theme(legend.position = &#39;bottom&#39;)

Gives us this plot:

R – 绘图中线交点的坐标

答案2

得分: 0

以下是翻译好的部分:

假设V2是离散的,所有的数据框都共享相同的V2值,另一种选择是使用optim来查找每个子范围内的交点:

  1. options(digits=20)
  2. funcLs <- lapply(list(df1, df2, df3), function(DF) approxfun(DF$V2, DF$V1))
  3. X <- df1$V2
  4. Filter(Negate(is.null), unlist(combn(funcLs, 2L, FUN=function(funcs) {
  5. mapply(function(lower, upper) {
  6. res <- optim((lower+upper)/2, function(x) abs(funcs[[1L]](x) - funcs[[2L]](x)),
  7. method="Brent", lower=lower, upper=upper, control=list(reltol=1e-10))
  8. if (res$value < 1e-4 && res$convergence==0L) return(res$par)
  9. }, X[-length(X)], X[-1L])
  10. }, simplify=FALSE), recursive=FALSE))

输出:

  1. [[1]]
  2. [1] 1.67425093704201
  3. [[2]]
  4. [1] 4.5626919006160991
  5. [[3]]
  6. [1] 5.3263874397151056
  7. [[4]]
  8. [1] 7.4859253126769065

检查:

  1. sapply(ans, function(x) all.equal(funcLs[[2L]](x), funcLs[[3L]](x)))
  2. #[1] TRUE TRUE TRUE TRUE
英文:

Assuming that V2 is discrete and all data.frames share the same values for V2, another option is using optim to find the intersections within each sub-range:

  1. options(digits=20)
  2. funcLs &lt;- lapply(list(df1, df2, df3), function(DF) approxfun(DF$V2, DF$V1))
  3. X &lt;- df1$V2
  4. Filter(Negate(is.null), unlist(combn(funcLs, 2L, FUN=function(funcs) {
  5. mapply(function(lower, upper) {
  6. res &lt;- optim((lower+upper)/2, function(x) abs(funcs[[1L]](x) - funcs[[2L]](x)),
  7. method=&quot;Brent&quot;, lower=lower, upper=upper, control=list(reltol=1e-10))
  8. if (res$value &lt; 1e-4 &amp;&amp; res$convergence==0L) return(res$par)
  9. }, X[-length(X)], X[-1L])
  10. }, simplify=FALSE), recursive=FALSE))

output:

  1. [[1]]
  2. [1] 1.67425093704201
  3. [[2]]
  4. [1] 4.5626919006160991
  5. [[3]]
  6. [1] 5.3263874397151056
  7. [[4]]
  8. [1] 7.4859253126769065

checks:

  1. sapply(ans, function(x) all.equal(funcLs[[2L]](x), funcLs[[3L]](x)))
  2. #[1] TRUE TRUE TRUE TRUE

huangapple
  • 本文由 发表于 2020年1月6日 21:43:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/59613207.html
匿名

发表评论

匿名网友

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

确定