<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/pretty-scatter-plots-with-ggplot2/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2"> blogR</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p><a target="_blank" rel="nofollow" href="https://twitter.com/drsimonj">@drsimonj</a> here to make pretty scatter plots of correlated variables with ggplot2!</p>
<p>We’ll learn how to create plots that look like this:</p>
<p><a target="_blank" rel="nofollow" href="https://i2.wp.com/svbtleusercontent.com/nvvxuthhlzemg.png?ssl=1"><img alt="init-example-1.png" src="https://i1.wp.com/svbtleusercontent.com/nvvxuthhlzemg_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#data_2"> </a>Data</h2>
<p>In a data.frame <code>d</code>, we’ll simulate two correlated variables <code>a</code> and <code>b</code> of length <code>n</code>:</p>
<pre><code>set.seed(170513)
n &lt;- 200
d &lt;- data.frame(a = rnorm(n))
d$b &lt;- .4 * (d$a + rnorm(n))

head(d)
#>            a           b
#> 1 -0.9279965 -0.03795339
#> 2  0.9133158  0.21116682
#> 3  1.4516084  0.69060249
#> 4  0.5264596  0.22471694
#> 5 -1.9412516 -1.70890512
#> 6  1.4198574  0.30805526
</code></pre>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#basic-scatter-plot_2"> </a>Basic scatter plot</h2>
<p>Using ggplot2, the basic scatter plot (with <code>theme_minimal</code>) is created via:</p>
<pre><code>library(ggplot2)

ggplot(d, aes(a, b)) +
  geom_point() +
  theme_minimal()
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i2.wp.com/svbtleusercontent.com/hbhsdeonvjlvw.jpeg?ssl=1"><img alt="unnamed-chunk-3-1.JPEG" src="https://i1.wp.com/svbtleusercontent.com/hbhsdeonvjlvw_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#shape-and-size_2"> </a>Shape and size</h2>
<p>There are many ways to tweak the <code>shape</code> and <code>size</code> of the points. Here’s the combination I settled on for this post:</p>
<pre><code>ggplot(d, aes(a, b)) +
  geom_point(shape = 16, size = 5) +
  theme_minimal()
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/svbtleusercontent.com/prd80u5fwjacw.jpeg?ssl=1"><img alt="unnamed-chunk-4-1.JPEG" src="https://i2.wp.com/svbtleusercontent.com/prd80u5fwjacw_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#color_2"> </a>Color</h2>
<p>We want to color the points in a way that helps to visualise the correlation between them.</p>
<p>One option is to <code>color</code> by one of the variables. For example, color by <code>a</code> (and hide legend):</p>
<pre><code>ggplot(d, aes(a, b, color = a)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE) +
  theme_minimal()
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/svbtleusercontent.com/iijlkiihme6rlw.jpeg?ssl=1"><img alt="unnamed-chunk-5-1.JPEG" src="https://i2.wp.com/svbtleusercontent.com/iijlkiihme6rlw_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Although it’s subtle in this plot, the problem is that the color is changing as the points go from left to right. Instead, we want the color to change in a direction that characterises the correlation – diagonally in this case.</p>
<p>To do this, we can color points by the <strong>first</strong> principal component. Add it to the data frame as a variable <code>pc</code> and use it to color like so:</p>
<pre><code>d$pc &lt;- predict(prcomp(~a+b, d))[,1]

ggplot(d, aes(a, b, color = pc)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE) +
  theme_minimal()
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/svbtleusercontent.com/acgkiogvjxz9w.jpeg?ssl=1"><img alt="unnamed-chunk-6-1.JPEG" src="https://i2.wp.com/svbtleusercontent.com/acgkiogvjxz9w_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Now we can add color, let’s pick something nice with the help of the <code>scale_color_gradient</code> functions and some nice hex codes (check out <a target="_blank" rel="nofollow" href="http://www.color-hex.com/">color-hex</a> for inspriation). For example:</p>
<pre><code>ggplot(d, aes(a, b, color = pc)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#0091ff&quot;, high = &quot;#f0650e&quot;)
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/svbtleusercontent.com/y3ffjbkmsdmr8w.jpeg?ssl=1"><img alt="unnamed-chunk-7-1.JPEG" src="https://i1.wp.com/svbtleusercontent.com/y3ffjbkmsdmr8w_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#transparency_2"> </a>Transparency</h2>
<p>Now it’s time to get rid of those offensive mushes by adjusting the transparency with <code>alpha</code>.</p>
<p>We could adjust it to be the same for every point:</p>
<pre><code>ggplot(d, aes(a, b, color = pc)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE, alpha = .4) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#0091ff&quot;, high = &quot;#f0650e&quot;)
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i0.wp.com/svbtleusercontent.com/s7ukxd5q8lttqa.jpeg?ssl=1"><img alt="unnamed-chunk-8-1.JPEG" src="https://i1.wp.com/svbtleusercontent.com/s7ukxd5q8lttqa_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>This is fine most of the time. However, what if you have many points? Let’s try with 5,000 points:</p>
<pre><code># Simulate data
set.seed(170513)
n &lt;- 5000
d &lt;- data.frame(a = rnorm(n))
d$b &lt;- .4 * (d$a + rnorm(n))

# Compute first principal component
d$pc &lt;- predict(prcomp(~a+b, d))[,1]

# Plot
ggplot(d, aes(a, b, color = pc)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE, alpha = .4) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#0091ff&quot;, high = &quot;#f0650e&quot;)
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i2.wp.com/svbtleusercontent.com/gqbax0bvlmxqyq.jpeg?ssl=1"><img alt="unnamed-chunk-9-1.JPEG" src="https://i1.wp.com/svbtleusercontent.com/gqbax0bvlmxqyq_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>We’ve got another big mush. What if we take <code>alpha</code> down really low to .05?</p>
<pre><code>ggplot(d, aes(a, b, color = pc)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE, alpha = .05) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#0091ff&quot;, high = &quot;#f0650e&quot;)
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i2.wp.com/svbtleusercontent.com/zliuy0syanmwow.jpeg?ssl=1"><img alt="unnamed-chunk-10-1.JPEG" src="https://i2.wp.com/svbtleusercontent.com/zliuy0syanmwow_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Better, except it’s now hard to see extreme points that are alone in space.</p>
<p>To solve this, we’ll map <code>alpha</code> to the <strong>inverse</strong> point density. That is, turn down <code>alpha</code> wherever there are lots of points! The trick is to use bivariate density, which can be added as follows:</p>
<pre><code># Add bivariate density for each point
d$density &lt;- fields::interp.surface(
  MASS::kde2d(d$a, d$b), d[,c(&quot;a&quot;, &quot;b&quot;)])
</code></pre>
<p>Now plot with <code>alpha</code> mapped to <code>1/density</code>:</p>
<pre><code>ggplot(d, aes(a, b, color = pc, alpha = 1/density)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#0091ff&quot;, high = &quot;#f0650e&quot;)
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i2.wp.com/svbtleusercontent.com/cez6zj7g3gnpfa.jpeg?ssl=1"><img alt="unnamed-chunk-12-1.JPEG" src="https://i1.wp.com/svbtleusercontent.com/cez6zj7g3gnpfa_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>You can see that distant points are now too vibrant. Our final fix is to use <code>scale_alpha</code> to tweak the alpha range. By default, this range is 0 to 1, making the most distant points have an alpha close to 1. Let’s restrict it to something better:</p>
<pre><code>ggplot(d, aes(a, b, color = pc, alpha = 1/density)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#0091ff&quot;, high = &quot;#f0650e&quot;) +
  scale_alpha(range = c(.05, .25))
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/svbtleusercontent.com/hlqpu7p0exdqg.jpeg?ssl=1"><img alt="unnamed-chunk-13-1.JPEG" src="https://i0.wp.com/svbtleusercontent.com/hlqpu7p0exdqg_small.jpeg?w=456&ssl=1" data-recalc-dims="1"></a></p>
<p>Much better! No more mushy patches or lost points.</p>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#bringing-it-together_2"> </a>Bringing it together</h2>
<p>Here’s a complete example with new data and colors:</p>
<pre><code># Simulate data
set.seed(170513)
n &lt;- 2000
d &lt;- data.frame(a = rnorm(n))
d$b &lt;- -(d$a + rnorm(n, sd = 2))

# Add first principal component
d$pc &lt;- predict(prcomp(~a+b, d))[,1]

# Add density for each point
d$density &lt;- fields::interp.surface(
  MASS::kde2d(d$a, d$b), d[,c(&quot;a&quot;, &quot;b&quot;)])

# Plot
ggplot(d, aes(a, b, color = pc, alpha = 1/density)) +
  geom_point(shape = 16, size = 5, show.legend = FALSE) +
  theme_minimal() +
  scale_color_gradient(low = &quot;#32aeff&quot;, high = &quot;#f2aeff&quot;) +
  scale_alpha(range = c(.25, .6))
</code></pre>
<p><a target="_blank" rel="nofollow" href="https://i0.wp.com/svbtleusercontent.com/3svtcqfu4ynitg.png?ssl=1"><img alt="unnamed-chunk-14-1.png" src="https://i0.wp.com/svbtleusercontent.com/3svtcqfu4ynitg_small.png?w=456&ssl=1" data-recalc-dims="1"></a></p>
<h2><a target="_blank" rel="nofollow" href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2#sign-off_2"> </a>Sign off</h2>
<p>Thanks for reading and I hope this was useful for you.</p>
<p>For updates of recent blog posts, follow <a target="_blank" rel="nofollow" href="https://twitter.com/drsimonj">@drsimonj</a> on Twitter, or email me at <a target="_blank" rel="nofollow" href="mailto:drsimonjackson@gmail.com">drsimonjackson@gmail.com</a> to get in touch.</p>
<p>If you’d like the code that produced this blog, check out the <a target="_blank" rel="nofollow" href="https://github.com/drsimonj/blogR">blogR GitHub repository</a>.</p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://drsimonj.svbtle.com/pretty-scatter-plots-with-ggplot2"> blogR</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/Rznq6F0Tzkc"></a></div>