I have a pretty big dataset (around 5e5 rows) of (x, y) coordinates with additional feature z. It's something like this:
x <- rnorm(1e6, 0, 5)
y <- rnorm(1e6, 0, 10)
dist <- sqrt(x^2 + y^2)
z <- exp(-(dist / 8)^2)
I want to plot them with a z feature used as a color aesthetic. But simple geom_point takes a while with such a big dataset:
data.frame(x, y, z) %>%
ggplot() + geom_point(aes(x, y, color = z))
So I think I need a way to aggregate points in some way. One approach would be to divide a plane to some small squares and average all the z values for points that lie in a square. But it can be a little cumbersome in the long term and it's probably better to use some of already available tools. So I thought about geom_hex as a geom that would look good in my case. But fill aesthetic is setup to count as default. So my questions are:
- Can default
fillvalue ofgeom_hexbe easily changed to an average ofzfeature? - If not, how can I create hexagons instead of squares, so that
zvalue can be averaged within hexagons and then plotted? - Is there any other way to improve a speed of plotting such a dataset?
Edit:
Comparison of proposed solutions:
library(microbenchmark)
microbenchmark(
'stat_summary_hex' = {data.frame(x, y, z) %>%
ggplot( aes(x, y, z=z )) + stat_summary_hex(fun = function(x) mean(x))},
'round_and_group' = {data.frame(x, y, z) %>%
mutate(x=round(x, 0), y=round(y, 0)) %>%
group_by(x,y) %>%
summarize(z = mean(z)) %>%
ggplot() + geom_hex(aes(x, y, fill = z), stat="identity")}
)
Unit: milliseconds
expr min lq mean median uq max neval
stat_summary_hex 2.243791 2.38539 2.454039 2.426123 2.50871 2.963176 100
round_and_group 183.785828 186.38851 188.296828 187.347476 189.10874 218.668487 100





