5

I'm writing a function that creates ggplot's scatter plot with size of points representing the number of points with the same X and Y coordinates.

I have a function that works:

require(dplyr)
plot_size_bubbles <- function(x,y) {
  dd = data.frame(x,y) %>%
    group_by(x,y) %>%
    summarise(n=n()) %>%
    ungroup()
  ggplot(dd, aes(x,y)) + geom_point(aes(size=n))
}

X = sample(1:3,10,replace = T)
Y = sample(1:3,10,replace = T)
plot_size_bubbles(X,Y)

I'd like to make it in ggplot's style as a custom geometry function inherited from geom_point. Maybe I can use some stat function, not sure. Basically I'd like to pass to ggplot a data frame, map x and y, and create this plot without prior calculating the points size. Like

ggplot(data.frame(X,Y), aes(X,Y)) + geom_sizebubble()

In addition it would be great to have x and y axes labels from the original data frame.

Hope it's possible and I'm just missing something.

Mike Wise
  • 22,131
  • 8
  • 81
  • 104
yuk
  • 19,098
  • 13
  • 68
  • 99

1 Answers1

6
stat_accum <- function(mapping = NULL, data = NULL,
                         geom = "point", position = "stack",
                         ...,
                         show.legend = NA,
                         inherit.aes = TRUE) {

  layer(
    data = data,
    mapping = mapping,
    stat = StatAccum,
    geom = geom,
    position = position,
    show.legend = show.legend,
    inherit.aes = inherit.aes,
    params = list(
      na.rm = na.rm,
      ...
    )
  )
}

StatAccum <- ggproto("StatAccum", Stat,
  compute_layer = function(data, scales, params) {
    odat <- dplyr::distinct(data, x, y, .keep_all=TRUE)
    data <- dplyr::count(data, x, y)
    data <- dplyr::left_join(data, odat, by=c("x", "y"))
    data$size <- data$n
    data$n <- NULL
    data
 }
)

set.seed(12)
dplyr::data_frame(
  X = sample(1:5, 100, replace = TRUE),
  Y = sample(1:5, 100, replace = TRUE)
) -> xdf

ggplot(xdf, aes(X, Y)) + geom_point()

enter image description here

ggplot(xdf, aes(X, Y)) + geom_point(stat="accum")

enter image description here

hrbrmstr
  • 77,368
  • 11
  • 139
  • 205
  • Thank you so much! This is exactly what I needed. I missed your answer when you published it, but it still valuable. – yuk Jan 23 '18 at 22:44