<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/hypothetical-outcome-plots/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://www.maxhumber.com/2017/02/03/hypothetical-outcomes.html"> max humber</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<div>
<pre><code><span>suppressPackageStartupMessages</span><span>(</span><span>library</span><span>(</span><span>tidyverse</span><span>))</span><span>
</span><span># devtools::install_github(&quot;dgrtwo/gganimate&quot;)
# install.packages(&quot;cowplot&quot;)
</span><span>library</span><span>(</span><span>gganimate</span><span>)</span><span>
</span><span># install image magick in terminal >> &quot;brew install image magick&quot;
</span></code></pre>
</div>
<p></p>
<p>If the Weatherman says that there is 30% chance of rain tomorrow. And it rains. Was he wrong? It’s an important question. Because it rained on November 8th. And a lot of people think that it wasn’t supposed to.</p>
<p>Communicating uncertainty is hard. It’s hard because uncertainty can be convoluted and opaque. And it’s hard because a lot of people can’t get down with boxplots or measures of spread.</p>
<p>Take this toy data for example:</p>
<div>
<pre><code><span>set.seed</span><span>(</span><span>2016</span><span>)</span><span>
</span><span>df</span><span> </span><span>&lt;-</span><span> </span><span>tibble</span><span>(</span><span>
</span><span>`Blue Team`</span><span> </span><span>=</span><span> </span><span>round</span><span>(</span><span>rnorm</span><span>(</span><span>50</span><span>,</span><span> </span><span>mean</span><span> </span><span>=</span><span> </span><span>48</span><span>,</span><span> </span><span>sd</span><span> </span><span>=</span><span> </span><span>5</span><span>)),</span><span> </span><span>`Red Team`</span><span> </span><span>=</span><span> </span><span>round</span><span>(</span><span>rnorm</span><span>(</span><span>50</span><span>,</span><span> </span><span>mean</span><span> </span><span>=</span><span> </span><span>45</span><span>,</span><span> </span><span>sd</span><span> </span><span>=</span><span> </span><span>3</span><span>))</span><span>
</span><span>)</span><span> </span><span>%>%</span><span> </span><span>mutate</span><span>(</span><span>simulation</span><span> </span><span>=</span><span> </span><span>row_number</span><span>())</span><span> </span><span>%>%</span><span> </span><span>gather</span><span>(</span><span>team</span><span>,</span><span> </span><span>probability</span><span>,</span><span> </span><span>-</span><span>simulation</span><span>)</span><span> </span><span>%>%</span><span> </span><span>mutate</span><span>(</span><span>probability</span><span> </span><span>=</span><span> </span><span>ifelse</span><span>(</span><span>probability</span><span> </span><span>>=</span><span> </span><span>100</span><span>,</span><span> </span><span>100</span><span>,</span><span> </span><span>probability</span><span>)</span><span> </span><span>/</span><span> </span><span>100</span><span>)</span><span>
</span></code></pre>
</div>
<p></p>
<p>Imagine that this data was generated from some model. How might we represent the uncertainty in our model and around our predictions?</p>
<p>Perhaps we might push the data through a boxplot:</p>
<div>
<pre><code><span>df</span><span> </span><span>%>%</span><span> </span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>team</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>probability</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_boxplot</span><span>()</span><span>
</span></code></pre>
</div>
<p><img alt="center" src="https://i2.wp.com/www.maxhumber.com/assets/img/hop_1.png?w=456" data-recalc-dims="1"></p>
<p>Or a density chart:</p>
<div>
<pre><code><span>df</span><span> </span><span>%>%</span><span> </span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>fill</span><span> </span><span>=</span><span> </span><span>team</span><span>))</span><span> </span><span>+</span><span> </span><span>geom_density</span><span>(</span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>/</span><span>2</span><span>)</span><span> </span><span>+</span><span> </span><span>scale_fill_manual</span><span>(</span><span>values</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>&quot;blue&quot;</span><span>,</span><span> </span><span>&quot;red&quot;</span><span>))</span><span>
</span></code></pre>
</div>
<p><img alt="center" src="https://i0.wp.com/www.maxhumber.com/assets/img/hop_2.png?w=456" data-recalc-dims="1"></p>
<p>Or use some errorbars:</p>
<div>
<pre><code><span>df</span><span> </span><span>%>%</span><span> </span><span>group_by</span><span>(</span><span>team</span><span>)</span><span> </span><span>%>%</span><span> </span><span>summarise</span><span>(</span><span>
</span><span>mean</span><span> </span><span>=</span><span> </span><span>mean</span><span>(</span><span>probability</span><span>),</span><span> </span><span>low</span><span> </span><span>=</span><span> </span><span>quantile</span><span>(</span><span>probability</span><span>,</span><span> </span><span>0.025</span><span>),</span><span>
</span><span>high</span><span> </span><span>=</span><span> </span><span>quantile</span><span>(</span><span>probability</span><span>,</span><span> </span><span>0.975</span><span>))</span><span> </span><span>%>%</span><span> </span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>team</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>mean</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_errorbar</span><span>(</span><span>aes</span><span>(</span><span>ymin</span><span> </span><span>=</span><span> </span><span>low</span><span>,</span><span> </span><span>ymax</span><span> </span><span>=</span><span> </span><span>high</span><span>))</span><span>
</span></code></pre>
</div>
<p><img alt="center" src="https://i1.wp.com/www.maxhumber.com/assets/img/hop_3.png?w=456" data-recalc-dims="1"></p>
<p>These options all kind of suck, though. They’re not super intuitive. And they aren’t all that convincing, because they can intimidate a lot of people!</p>
<p>Instead of boxplots or density charts or regular errorbars we can hack errorbars to generate a proto-Hypothetical Outcome Plot:</p>
<div>
<pre><code><span>df</span><span> </span><span>%>%</span><span> </span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>team</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>probability</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_errorbar</span><span>(</span><span>aes</span><span>(</span><span>ymin</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>ymax</span><span> </span><span>=</span><span> </span><span>probability</span><span>))</span><span>
</span></code></pre>
</div>
<p><img alt="center" src="https://i2.wp.com/www.maxhumber.com/assets/img/hop_4.png?w=456" data-recalc-dims="1"></p>
<p>Hypothetical Outcome Plots (HOPs) are a way to build and visualize uncertainty in the same way that we experience it (in and by countable events). The depth and theory behind HOPs is beyond the scope of this quick post, but if you’re interested in learning more check out <a target="_blank" rel="nofollow" href="https://medium.com/hci-design-at-uw/hypothetical-outcomes-plots-experiencing-the-uncertain-b9ea60d7c740#.taennvi6g">this awesome Medium story</a> by the <em>UW Interactive Data Lab</em>.</p>
<p>Extending our hacked errorbars with <code>gganimate</code> we can implement an actual HOP in just a few lines of R:</p>
<div>
<pre><code><span>p</span><span> </span><span>&lt;-</span><span> </span><span>df</span><span> </span><span>%>%</span><span> </span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>team</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>frame</span><span> </span><span>=</span><span> </span><span>simulation</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_errorbar</span><span>(</span><span>aes</span><span>(</span><span>ymin</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>ymax</span><span> </span><span>=</span><span> </span><span>probability</span><span>))</span><span>
</span><span>gganimate</span><span>(</span><span>p</span><span>,</span><span> </span><span>title_frame</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span></code></pre>
</div>
<p><img alt="center" src="https://i2.wp.com/www.maxhumber.com/assets/img/hop_5.gif?w=456" data-recalc-dims="1"></p>
<p>In this way we can directly experience the uncertainty of our model and the predictions that it happens to make.</p>
<p>In looking at the HOP it seems as though the Blue Team is supposed to win our imaginary game. Importantly, however, the Red Team comes up on top in certain simulations. So, don’t say that the model is wrong if they happen to actually win our imaginary game!</p>
<p>If you want to add a little polish to your HOP, I might suggest extending it with some ghost bars:</p>
<div>
<pre><code><span>p</span><span> </span><span>&lt;-</span><span> </span><span>df</span><span> </span><span>%>%</span><span>
</span><span>ggplot</span><span>(</span><span>aes</span><span>(</span><span>x</span><span> </span><span>=</span><span> </span><span>team</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>probability</span><span>))</span><span> </span><span>+</span><span>
</span><span>geom_errorbar</span><span>(</span><span>aes</span><span>(</span><span>
</span><span>ymin</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>ymax</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>frame</span><span> </span><span>=</span><span> </span><span>simulation</span><span>,</span><span> </span><span>cumulative</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>),</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>&quot;grey80&quot;</span><span>,</span><span> </span><span>alpha</span><span> </span><span>=</span><span> </span><span>1</span><span>/</span><span>8</span><span>)</span><span> </span><span>+</span><span>
</span><span>geom_errorbar</span><span>(</span><span>aes</span><span>(</span><span>
</span><span>ymin</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>ymax</span><span> </span><span>=</span><span> </span><span>probability</span><span>,</span><span> </span><span>frame</span><span> </span><span>=</span><span> </span><span>simulation</span><span>),</span><span> </span><span>color</span><span> </span><span>=</span><span> </span><span>&quot;#00a9e0&quot;</span><span>)</span><span> </span><span>+</span><span>
</span><span>scale_y_continuous</span><span>(</span><span>
</span><span>limits</span><span> </span><span>=</span><span> </span><span>c</span><span>(</span><span>0</span><span>,</span><span> </span><span>1</span><span>),</span><span> </span><span>labels</span><span> </span><span>=</span><span> </span><span>scales</span><span>::</span><span>percent_format</span><span>())</span><span> </span><span>+</span><span>
</span><span>theme</span><span>(</span><span>panel.background</span><span> </span><span>=</span><span> </span><span>element_rect</span><span>(</span><span>fill</span><span> </span><span>=</span><span> </span><span>&quot;#FFFFFF&quot;</span><span>))</span><span> </span><span>+</span><span>
</span><span>labs</span><span>(</span><span>title</span><span> </span><span>=</span><span> </span><span>&quot;&quot;</span><span>,</span><span> </span><span>y</span><span> </span><span>=</span><span> </span><span>&quot;Probability of winning&quot;</span><span>,</span><span> </span><span>x</span><span> </span><span>=</span><span> </span><span>&quot;&quot;</span><span>)</span><span>
</span><span>gganimate</span><span>(</span><span>p</span><span>,</span><span> </span><span>title_frame</span><span> </span><span>=</span><span> </span><span>FALSE</span><span>)</span><span>
</span></code></pre>
</div>
<p><img alt="center" src="https://i0.wp.com/www.maxhumber.com/assets/img/hop_6.gif?w=456" data-recalc-dims="1"></p>
<p>But that’s it. Thanks for reading!</p>
<p>I have two more posts in the queue about visualizing models and model performance. Look for them in the near future!</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://www.maxhumber.com/2017/02/03/hypothetical-outcomes.html"> max humber</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/uJZKGju_Ej4"></a></div>