Why is bins parameter unknown for the stat_density2d function? (ggmap)

故事扮演 提交于 2019-12-03 22:48:31

Okay, adding this one as a second answer because I think the descriptions and comments in the first answer are useful and I don't feel like merging them. Basically I figured there must be an easy way to restore the regressed functionality. And after awhile, and learning some basics about ggplot2, I got this to work by overriding some ggplot2 functions:

library(ggmap)
library(ggplot2)

# -------------------------------
# start copy from stat-density-2d.R

stat_density_2d <- function(mapping = NULL, data = NULL, geom = "density_2d",
                            position = "identity", contour = TRUE,
                            n = 100, h = NULL, na.rm = FALSE,bins=0,
                            show.legend = NA, inherit.aes = TRUE, ...) {
  layer(
    data = data,
    mapping = mapping,
    stat = StatDensity2d,
    geom = geom,
    position = position,
    show.legend = show.legend,
    inherit.aes = inherit.aes,
    params = list(
      na.rm = na.rm,
      contour = contour,
      n = n,
      bins=bins,
      ...
    )
  )
}

stat_density2d <- stat_density_2d

StatDensity2d <- 
  ggproto("StatDensity2d", Stat,
          default_aes = aes(colour = "#3366FF", size = 0.5),

          required_aes = c("x", "y"),

          compute_group = function(data, scales, na.rm = FALSE, h = NULL,
                                   contour = TRUE, n = 100,bins=0) {
            if (is.null(h)) {
              h <- c(MASS::bandwidth.nrd(data$x), MASS::bandwidth.nrd(data$y))
            }

            dens <- MASS::kde2d(
              data$x, data$y, h = h, n = n,
              lims = c(scales$x$dimension(), scales$y$dimension())
            )
            df <- data.frame(expand.grid(x = dens$x, y = dens$y), z = as.vector(dens$z))
            df$group <- data$group[1]

            if (contour) {
              #  StatContour$compute_panel(df, scales,bins=bins,...) # bad dots...
              if (bins>0){
                StatContour$compute_panel(df, scales,bins)
              } else {
                StatContour$compute_panel(df, scales)
              }
            } else {
              names(df) <- c("x", "y", "density", "group")
              df$level <- 1
              df$piece <- 1
              df
            }
          }
  )

# end copy from stat-density-2d.R
# -------------------------------

set.seed(1)
n=100

df <- data.frame(x=rnorm(n, 0, 1), y=rnorm(n, 0, 1))

TestData <- ggplot (data = df) +
  stat_density2d(aes(x = x, y = y,fill = as.factor(..level..)),bins=5,geom = "polygon") +
  geom_point(aes(x = x, y = y)) +
  scale_fill_manual(values = c("yellow","red","green","royalblue", "black"))
print(TestData)

Which yields the result. Note that varying the bins parameter has the desired effect now, which cannot be replicated by varying the n parameter.

Mike Wise

update:

After an extended discussion with Roland (see the comments), he determined it is probably a regression bug and filed a bug report.


As the question is "why is the bins parameter unknown?", and I spent a fair amount of time researching it, I will answer it.

Your example obviously comes from this link from Oct 2013, where the parameter is used. How to correctly interpret ggplot's stat_density2d

However it was never a documented parameter, and it is not clear that it is being used there. It is probably a parameter that is being passed through to other libraries (like MASS) that are being used by stat_density2d.

We can get the code to work by getting rid of the scale_fill_manual call and using this:

library(ggmap)
set.seed(1)
n=100

df <- data.frame(x=rnorm(n, 0, 1), y=rnorm(n, 0, 1))

TestData <- ggplot (data = df) +
  stat_density2d(aes(x = x, y = y,fill = as.factor(..level..)), geom = "polygon",) +
  geom_point(aes(x = x, y = y)) 
#  scale_fill_manual(values = c("yellow","red","green","royalblue", "black"))
print(TestData)

which yields this:

Since this looks rather different from the plot posted in the original Oct 2013 link, I would say that stat_density2d has been extensively rewritten since then, or maybe MASS:kde2d (or another MASS routine), and that the bin parameter is no longer accepted. It is also not clear that that parameter ever did anything (read the link).

You can however vary the parameters n and h - also undocumented from the stat_density2d point-of-view (as far as I can tell).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!