【问题标题】:stat_density2d - What does the legend mean?stat_density2d - 图例是什么意思?
【发布时间】:2018-11-06 12:45:33
【问题描述】:

我在 R 中使用stat_density2d 完成了地图。这是代码:

ggplot(data, aes(x=Lon, y=Lat)) + 
  stat_density2d(aes(fill = ..level..), alpha=0.5, geom="polygon",show.legend=FALSE)+
  geom_point(colour="red")+
  geom_path(data=map.df,aes(x=long, y=lat, group=group), colour="grey50")+
  scale_fill_gradientn(colours=rev(brewer.pal(7,"Spectral")))+
  xlim(-10,+2.5) +
  ylim(+47,+60) +
  coord_fixed(1.7) +
  theme_void()

它会产生这个:

太好了。有用。但是我不知道传说是什么意思。我确实找到了这个维基百科页面:

https://en.wikipedia.org/wiki/Multivariate_kernel_density_estimation

他们使用的示例(包含红色、橙色和黄色)表示:

彩色轮廓对应于包含的最小区域 各自的概率质量:红色 = 25%,橙色 + 红色 = 50%,黄色 + 橙色 + 红色 = 75%

但是,使用 stat_density2d,我的地图中有 11 个等高线。有谁知道 stat_density2d 的工作原理以及图例的含义?理想情况下,我希望能够说明红色轮廓包含 25% 的图等内容。

我已经读过这个:https://ggplot2.tidyverse.org/reference/geom_density_2d.html,但我仍然没有更聪明。

【问题讨论】:

  • 谢谢。我会消化链接:)
  • 我看到你在那里发帖,但我仍然不确定我应该如何解释结果,即每个级别的含义是什么?我问,因为有人问我每个轮廓的含义,我无法解释。是不是很简单“如果有10个级别,那就意味着每个级别都是10%”,所以标记为红色的数据是最密集的10%,下一个级别是最密集的20%等

标签: r stat-density2d


【解决方案1】:

让我们以 ggplot2 中的 faithful 为例:

ggplot(faithful, aes(x = eruptions, y = waiting)) +
  stat_density_2d(aes(fill = factor(stat(level))), geom = "polygon") +
  geom_point() +
  xlim(0.5, 6) +
  ylim(40, 110)

(提前道歉没有让这个更漂亮)

级别是 3D“山”被切片的高度。我不知道有什么方法(其他人可能会)将其转换为百分比,但我确实知道让你说百分比。

如果我们查看该图表,0.002 级别包含绝大多数点(除了 2 个)。级别0.004 实际上是 2 个多边形,它们包含除了大约十几个点之外的所有点。如果我得到了您要问的要点,那就是您想知道的,除了不计数,而是给定级别的多边形所包含的点的百分比。使用所涉及的各种 ggplot2“统计数据”中的方法可以直接计算。

请注意,当我们导入 tidyversesp 包时,我们将使用其他一些完全限定的函数。现在,让我们稍微重塑一下faithful 数据:

library(tidyverse)
library(sp)

xdf <- select(faithful, x = eruptions, y = waiting)

(更容易输入xy

现在,我们将按照 ggplot2 的方式计算二维核密度估计:

h <- c(MASS::bandwidth.nrd(xdf$x), MASS::bandwidth.nrd(xdf$y))

dens <- MASS::kde2d(
  xdf$x, xdf$y, h = h, n = 100,
  lims = c(0.5, 6, 40, 110)
)

breaks <- pretty(range(zdf$z), 10)

zdf <- data.frame(expand.grid(x = dens$x, y = dens$y), z = as.vector(dens$z))

z <- tapply(zdf$z, zdf[c("x", "y")], identity)

cl <- grDevices::contourLines(
  x = sort(unique(dens$x)), y = sort(unique(dens$y)), z = dens$z,
  levels = breaks
)

我不会用str() 输出来混淆答案,但看看那里发生的事情会很有趣。

我们可以使用空间操作来计算有多少点落在给定的多边形内,然后我们可以将多边形分组到同一级别以提供每个级别的计数和百分比:

SpatialPolygons(
  lapply(1:length(cl), function(idx) {
    Polygons(
      srl = list(Polygon(
        matrix(c(cl[[idx]]$x, cl[[idx]]$y), nrow=length(cl[[idx]]$x), byrow=FALSE)
      )),
      ID = idx
    )
  })
) -> cont

coordinates(xdf) <- ~x+y

data_frame(
  ct = sapply(over(cont, geometry(xdf), returnList = TRUE), length),
  id = 1:length(ct),
  lvl = sapply(cl, function(x) x$level)
) %>% 
  count(lvl, wt=ct) %>% 
  mutate(
    pct = n/length(xdf),
    pct_lab = sprintf("%s of the points fall within this level", scales::percent(pct))
  )
## # A tibble: 12 x 4
##      lvl     n    pct pct_lab                              
##    <dbl> <int>  <dbl> <chr>                                
##  1 0.002   270 0.993  99.3% of the points fall within this level
##  2 0.004   259 0.952  95.2% of the points fall within this level
##  3 0.006   249 0.915  91.5% of the points fall within this level
##  4 0.008   232 0.853  85.3% of the points fall within this level
##  5 0.01    206 0.757  75.7% of the points fall within this level
##  6 0.012   175 0.643  64.3% of the points fall within this level
##  7 0.014   145 0.533  53.3% of the points fall within this level
##  8 0.016    94 0.346  34.6% of the points fall within this level
##  9 0.018    81 0.298  29.8% of the points fall within this level
## 10 0.02     60 0.221  22.1% of the points fall within this level
## 11 0.022    43 0.158  15.8% of the points fall within this level
## 12 0.024    13 0.0478  4.8% of the points fall within this level 

我只是把它拼出来以避免更多的废话,但百分比会根据你如何修改密度计算的各种参数而改变(我的ggalt::geom_bkde2d() 使用不同的估计器也是如此)。

如果有一种方法可以在不重新执行计算的情况下梳理出百分比,那么没有比让其他 SO R 人员展示他们比撰写此答案的人聪明得多(希望以比最近看起来更外交的方式)。

【讨论】:

  • 嘿。我无法用语言形容你的回答有多大帮助。这就是我想要的答案,还有更多!感谢您花时间回复。明天我一回来工作,我就会运行额外的代码,这样我就会对它们做出回应,他们会很高兴的!
  • 很高兴为您提供帮助,我可以 PR 到 ggplot2 中将其添加为额外的计算统计数据,可用于图例与级别,因为我也认为它更有用。
  • 嘿,代码运行但没有得到我想要的响应,不幸的是,它只显示了 9 个级别而不是 12 个级别,其中 5 个级别没有数据。我注意到您在创建 zdf 之前创建了中断,所以我移动了它。有什么我必须更改以使其适合我的数据吗?我正在使用经度和纬度,我的“xdf”包含对这些经度/纬度的 664 个观测值。
  • 如果您想看一下,这是我的“xdf”数据:1drv.ms/u/s!AoBBWjKJEd_Eg9BqSK0gAkc0_3uCAQ
  • #ty!我很少在 $DAYJOB 中使用空间数据(我从事网络安全工作),所以任何时候我都可以使用现实世界的空间数据!
猜你喜欢
  • 2015-11-19
  • 1970-01-01
  • 2021-09-15
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多