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.
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.
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() .
The function geom_point() adds a layer of points to your plot, which creates a scatterplot.
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.
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()
ggplot(xdf, aes(X, Y)) + geom_point(stat="accum")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With