Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing ggplot custom geometry function

Tags:

r

ggplot2

ggproto

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.

like image 854
yuk Avatar asked Aug 30 '16 03:08

yuk


People also ask

What is %>% in Ggplot?

the %>% is a pipe operator that is actually part of the dplyr library (along with the filter function) not from the ggplot2 library. To sample 1%, there is a sample_frac function in the dplyr library.

What is AES () in Ggplot?

aes() is a quoting function. This means that its inputs are quoted to be evaluated in the context of the data. This makes it easy to work with variables from the data frame because you can name those directly. The flip side is that you have to use quasiquotation to program with aes() .

What does Geom_point () do in R?

The function geom_point() adds a layer of points to your plot, which creates a scatterplot.

Which geometrical object may be used to annotate a plot in ggplot2?

Method 1: Using geom_text() This allows annotating only text to a plot. This function along with the required parameters is added to the plot.


1 Answers

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

like image 105
hrbrmstr Avatar answered Sep 28 '22 23:09

hrbrmstr