smoothScatter with ggplot2

[This article was first published on INWT-Blog-RBloggers, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

The motivation for this plot is the function: graphics::smoothScatter, basically a plot of a two dimensional density estimator. In the following I want to reproduce the features with ggplot2.


To have some data I draw some random numbers from a two dimensional normal distribution:

<pre class ="r"><code>library(ggplot2) library(MASS) set.seed(2) dat <- data.frame(   mvrnorm(n = 1000,            mu = c(0, 0),            Sigma = matrix(rep(c(1, 0.2), 2), nrow = 2, ncol = 2))) names(dat) <- c("x", "y") </code>

smoothScatter is basically a scatter plot with a two dimensional density estimation. This is nice especially in the case of a lot of observations and for outlier detection.

<pre class="r"><code>par(mfrow = c(1,2)) plot(dat$x, dat$y) smoothScatter(dat$x, dat$y) </code>

smoothScatter in ggplot2

OK, very pretty, lets reproduce this feature in ggplot2. First thing is to add the necessary layers, which I already mentioned is a two dimensional density estimation, combined with the geom called ‘tile’. Also I use the fill aesthetic to add colour and a different palette:

<pre class ="r"><code>ggplot(data = dat, aes(x, y)) +   stat_density2d(aes(fill = ..density..^0.25), geom = "tile", contour = FALSE, n = 200) +   scale_fill_continuous(low = "white", high = "dodgerblue4")</code>

I add one additional layer; a simple scatter plot. To make the points transparent I choose alpha to be 1/10 which is a relative quantity with respect to the number of observations.

<pre class ="r"><code>last_plot() +   geom_point(alpha = 0.1, shape = 20)</code>

A similar approach is also discussed on StackOverflow. Actually that version is closer to smoothScatter.

Changing the theme

The last step is to tweak the theme-elements. Not that the following adds to any form of information but it looks nice. Starting from a standard theme, theme_classic, which is close to where I want to get, I get rid of all labels, axis and the legend.

<pre class ="r"><code>last_plot() +   theme_classic() +   theme(     legend.position = "none",      axis.line = element_blank(),      axis.ticks = element_blank(),      axis.text = element_blank(),      text = element_blank(),      plot.margin = unit(c(-1, -1, -1, -1), "cm")   ) </code>

The last thing is to save the plot in the correct format for display:

<pre class="r"><code>ggsave(   "scatterFinal.png",    plot = last_plot(),    width = 14,    height = 8,    dpi = 300,    units = "in" ) </code>

And that’s it, a nice picture which used to be a statistical graph.

To leave a comment for the author, please follow the link and comment on their blog: INWT-Blog-RBloggers. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)