<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/visualising-us-voting-records-with-shinydashboard/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://www.gokhanciflikli.com/post/adavis/"> Computational Social Science</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<div>
<h3>Introducing adavis</h3>
<p>My second ever post on this blog was on introducing <a rel="nofollow" href="https://www.gokhanciflikli.com/post/mapping-ada/" target="_blank">adamap</a>, a Shiny app that maps Americans for Democratic Action <a rel="nofollow" href="http://www.adaction.org/pages/publications/voting-records.php" target="_blank">voting scores</a> (the so-called <em>Liberal Quotient</em>) between 1947-2015. It was built with <code>highcharter</code>, and hence it was nicely interactive but quite slow. I wanted to switch to another package since, and when I eventually ran into <code>statebins</code>, I knew what had to be done.</p>
<p>I was certain that <code>statebins</code> would definitely add some oomph to the design, but because it’s so easy to implement, I had some spare time to do other things. As it is often the case, one thing led to the other, and I came to the conclusion that the revamped app should feature one plot from every major graphics package. Of course, a strict implementation of that statement would be quite difficult, so I downgraded the challenge to just four plots using a different package each time. I ended with <code>statebins</code> for state-level mapping, <code>plotly</code> for plotting changes from the previous year, <code>ggExtra</code> for head-to-head state comparisons, and *drum roll* base R for graphing a single politican’s voting record over time. It turned out to be fun.</p>
<p>As I have already explained the data setup in my previous post linked above, I will skip to the visualisations. I won’t be including the actual code for the Shiny app, which includes reactive elements throughout. You can fork the code underlying the live dashboard on <a rel="nofollow" href="https://github.com/ciflikli/adavis" target="_blank">GitHub</a> and/or run a local copy via the <code>runGitHub</code> code provided there. Also, none of the codes are evaluated here (as I translate them from the app), so they will not work if you just plug them in. Hence, there are primarily for motivation rather than replication.</p>
</div>
<div>
<h3>Slicker US with Statebins</h3>
<p>There are many good things about <code>statebins</code>. First, you get identical-sized states so you don’t get biased by the variation in their size. It’s cleaner by definition, not featuring idiosyncratic shapes that are found in nature. Also, it plays really nice with <code>viridis</code>, which is important (maybe). In addition, you can define light and dark labels for the state abbreviations, ensuring they will not blend into the fill colour. <code>statebins</code> can be called as a function (as I did), or applied later to a <code>ggplot</code> object. The only thing that did not work for me was the <code>ggplot2_scale_function</code> argument; R kept saying no such function is defined (I’m using the dev version from GitHub) so I ended up passing the fill colours separately. It gives a warning about overriding the existing fill, but works otherwise. If you download the dataset and want to visualise how House Democrats in 1962 voted, something along the lines of:</p>
<pre><code>#Not evaluated
library(ggplot2)
library(viridis)
library(statebins)
library(hrbrthemes)
theme_set(theme_ipsum_rc())

#assumes data = data, year as &quot;Year&quot;, state names in &quot;State&quot;, voting scores in &quot;ADA&quot; etc.
us &lt;- statebins(data[data$Year == 1962 &amp; data$Chamber == 1 &amp; data$Party == &quot;Democrat&quot;, ],
                state_col = &quot;State&quot;, value_col = &quot;ADA&quot;,
                round = TRUE, font_size = 7, state_border_col = &quot;#232d33&quot;,
                dark_label = &quot;white&quot;,
                light_label = &quot;black&quot;,
                state_border_size = .8, radius = grid::unit(10, &quot;pt&quot;)) +
          labs(title = &quot;&quot;) +
          theme(axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(),
                panel.grid.minor = element_blank(), panel.grid.major = element_blank(),
                panel.background = element_rect(fill = &quot;white&quot;, linetype = &quot;blank&quot;),
                legend.position = c(.075, .85), legend.direction = &quot;horizontal&quot;,
                legend.text = element_text(colour = &quot;#232d33&quot;, size = 14),
                legend.title = element_text(colour = &quot;#232d33&quot;, size = 18),
                legend.key.height = grid::unit(.01, &quot;snpc&quot;),
                legend.key.width = grid::unit(.05, &quot;snpc&quot;),
                plot.margin = margin(-1, 0, 0, 0, &quot;cm&quot;))
    us + scale_fill_viridis(direction = -1,
         breaks = c(seq(-25, 100, 25)),
         labels = c(&quot;No Rep&quot;, paste(seq(0, 100, 25), &quot;%  &quot;)),
         guide = guide_legend(title = &quot;&quot;, title.position = &quot;top&quot;,
                              keywidth = 2, keyheight = 2, ncol = 1))</code></pre>
<div><img src="https://i1.wp.com/www.gokhanciflikli.com/img/statebins.png?w=456&ssl=1" data-recalc-dims="1"></div>
<p>should do the trick. Now, I am totally cheating because the image is from the live app and the above code is not evaluated. However, it should give you an idea, mainly most of the clutter is about the layout rather than the content. Can we get someone with clout to ping Hadley and Bob regarding any updates on <a rel="nofollow" href="https://github.com/hrbrmstr/statebins/issues/4" target="_blank">issue#4</a> from 2015 so we get magically created bins (and other shapes, for the ambitious) not just for US states but for everything? Cheers.</p>
<p>One trick regarding the data; the original data only have scores for selected representatives (naturally). Meaning, in any given year, there will be several states (approx. 8-10 per party) with no Democrat or Republican reps. As these are row-wise missing instead of <code>NA</code>, if you plot them as they are, those states will not show in the plot. If only there was a tidyverse <a rel="nofollow" href="http://www.imachordata.com/you-complete-me/" target="_blank">function</a> that would solve common data problems like this…</p>
<pre><code>library(tidyverse)
#Add rows for missing states in party-year
#Use built-in states data
states &lt;- data.frame(state.name, stringsAsFactors = FALSE)
states$state.no &lt;- 1:50
dataset &lt;- merge(dataset, states, by.x = &quot;State&quot;, by.y = &quot;state.name&quot;)
#I couldn't get this to work with strings so matched them by state.no
dataset &lt;- dataset %>% tidyr::complete(state.no = full_seq(state.no, period = 1), Year, Chamber, Party,
                                       fill = list(ADA = -25, aADA = -25)) #Arbitrary low score instead of NA
dataset$State &lt;- ifelse(is.na(dataset$State), states[dataset$state.no, 1], dataset$State)</code></pre>
</div>
<div>
<h3>Interactive Charts with Plotly</h3>
<p>Moving on to challenge number #2, I wanted to keep to the same filter (Year > Chamber > Party), but with the amount of change from last year plotted instead. I haven’t used <code>plotly</code> much before so I learned on-the-go, but it has robust <a rel="nofollow" href="https://plotly-book.cpsievert.me/index.html" target="_blank">documentation</a> if you are considering delving into it.</p>
<p>The main reason for going with plotly was its build-in interactivity. I wanted the users to just hover over points and see a block of text describing the shift from the previous year. This turned out to be easy, just with a somewhat ugly <code>paste</code>. One curious thing was the alpha functionality, which is governed with <code>toRGB(&quot;colour&quot;, &quot;alpha&quot;)</code>, but called opacity in <code>plotly</code>. In the app, the default is showing Senate Republicans in 1990 (i.e. difference from 1989):</p>
<pre><code>library(plotly)
#Store common args
ax &lt;- list(
      showline = FALSE,
      showticklabels = TRUE,
      showgrid = FALSE)
#Mandatory data should be subsetted before comment
plot_ly(data, x = ~Score, key = data[, 1],
        y = ~Change, mode = &quot;markers&quot;, type = &quot;scatter&quot;, hoverinfo = &quot;text&quot;,
        hoverlabel = list(font = list(family = &quot;Roboto Condensed&quot;, size = 14)),
        #Add custom hover text
        text = ~paste(data$Chamber, data$Party, &quot;from&quot;,
        State, &quot;voted\n&quot;, paste0(abs(round(Change, 2)), &quot;% more&quot;), Label, &quot;in&quot;, data$Year),
        color = ~Change, colors = viridis(direction = -1, n = 12),
        marker = list(size = 30, opacity = .7)) %>%
      layout(dragmode = &quot;select&quot;, showlegend = FALSE,
        xaxis = c(ax, list(title = &quot;Selected Year Voting Score&quot;, zeroline = FALSE)),
        yaxis = c(ax, list(title = &quot;Change from Last Year&quot;, zeroline = TRUE, zerolinecolor = toRGB(&quot;black&quot;, .05))),
        font = list(family = &quot;Roboto Condensed&quot;)) %>%
      config(displayModeBar = FALSE)</code></pre>
<div><img src="https://i2.wp.com/www.gokhanciflikli.com/img/plotly.png?w=456&ssl=1" data-recalc-dims="1"></div>
<p>I admit today’s code chunks are a bit like <a rel="nofollow" href="https://i.pinimg.com/originals/3f/21/46/3f2146a7d6f8c3bdecacc9dff97c9a6e.jpg" target="_blank">this</a>, so if you have any questions, just fire away.</p>
</div>
<div>
<h3>Last but not least…Base R</h3>
<p>When I saw this brilliant post on <a rel="nofollow" href="http://motioninsocial.com/tufte/" target="_blank">Tufte</a>, the plot I wanted to replicate the most was the very first one. The one that was done in base R. Some might even argue I added a representative look-up tab to the app just for trying this out. Hmm. Like <code>plotly</code>, I was out of practice with base R graphics, so I mimicked the original code as much as I could. One thing I wanted to convey with this graph is the consistency of a single politician over their tenure. I didn’t want to show minima and maxima, but just their mean score with some sort of confidence measure. I also learned that you can pass Greek letters with <code>expression()</code>, which is handy. Say, you want to plot the complete voting history of Nancy Pelosi:</p>
<pre><code>#Store descriptives
v1 &lt;- mean(data$Score)
v2 &lt;- sd(data$Score)
v3 &lt;- min(data$Year)
v4 &lt;- max(data$Year)
v5 &lt;- summary(data$Year)

#Base plot, data should be a representative subset
plot(data$Score ~ data$Year, xlab = &quot;&quot;, ylab = &quot;&quot;, axes = FALSE, family = &quot;Roboto Condensed&quot;,
     pch = 16, type = &quot;b&quot;, lwd = 2)
#Upper sd
abline(h = v1 + v2, lty = 2, col = alpha(&quot;black&quot;, .2))
#Mean
abline(h = v1, lty = 2)
#Lower sd
abline(h = v1 - v2, lty = 2, col = alpha(&quot;black&quot;, .2))
#Right axis
axis(1, at = c(v3, v4, (v3 + v4) / 2),
     labels = c(v3, v4, round((v3 + v4) / 2, 0)),
     tick = FALSE, family = &quot;Roboto Condensed&quot;)
#Bottom axis
axis(2, at = c(v1, v1 + v2, v1 - v2), labels = round(c(v1, v1 + v2, v1 - v2), 0),
     las = 2, family = &quot;Roboto Condensed&quot;, tick = FALSE, lty = 0)
#Left axis
axis(4, at = c(v1, v1 + v2, v1 - v2), lwd = 0, las = 2,
     labels = c(expression(mu), expression(sigma), expression(sigma)),
     col = alpha(&quot;black&quot;, .2), family = &quot;Roboto Condensed&quot;, ps = 20)</code></pre>
<div><img src="https://i1.wp.com/www.gokhanciflikli.com/img/pelosi.png?w=456&ssl=1" data-recalc-dims="1"></div>
</div>
<div>
<h3>Viridis Options</h3>
<p>I might be relying on <code>viridis</code> a lot, although I also utilise the <code>RColorBrewer</code> package as well (<a rel="nofollow" href="https://www.gokhanciflikli.com/img/westeros_hires.png" target="_blank">Map of Westeros</a>, anyone?). To be honest, I more or less only like the default palette, the namesake or <code>option = &quot;D&quot;</code>, but others might fancy some good old diversity. To this end, I added a drop-down menu for switching <code>viridis</code> palettes, and a button for changing the direction (i.e. whether the palette should start from the lightest or the darkest colour). Both of these options are global, so you can switch any time at any tab. Except for the base R plot; that looks much better in black, <em>Tufte</em> style.</p>
<div><img src="https://i1.wp.com/image.ibb.co/cpBpKw/anim.gif?w=456&ssl=1" data-recalc-dims="1"></div>
</div>
<p><strong><a rel="nofollow" href="https://blockads.fivefilters.org/" target="_blank">Let’s block ads!</a></strong> <a rel="nofollow" href="https://blockads.fivefilters.org/acceptable.html" target="_blank">(Why?)</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="https://www.gokhanciflikli.com/post/adavis/"> Computational Social Science</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 rel="nofollow" href="https://www.r-project.org/" title="The R Project for Statistical Computing">R</a> news and <a rel="nofollow" href="https://www.r-bloggers.com/search/tutorial" title="R tutorials">tutorials</a> on topics such as: <a rel="nofollow" href="https://www.r-bloggers.com/search/data%20science" title="Data science">Data science</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data" title="Big Data">Big Data, <a rel="nofollow" href="https://www.r-users.com/" title="R jobs">R jobs</a>, visualization (<a rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2" title="ggplot and ggplot2 tutorials">ggplot2</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/boxplot" title="Boxplots using lattice and ggplot2 tutorials">Boxplots</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/map" title="Maps and gis">maps</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/animation" title="Animation in R">animation</a>), programming (<a rel="nofollow" href="https://www.r-bloggers.com/search/RStudio" title="RStudio IDE for R">RStudio</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/sweave" title="Sweave and literate programming">Sweave</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX" title="LaTeX in R">LaTeX</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/SQL" title="SQL and databases">SQL</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/eclipse" title="Eclipse IDE for R">Eclipse</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/git" title="git and github, Version Control System">git</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/hadoop" title="Large data in R using Hadoop">hadoop</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping" title="Web Scraping of google, facebook, yahoo, twitter and more using R">Web Scraping</a>) statistics (<a rel="nofollow" href="https://www.r-bloggers.com/search/regression" title="Regressions and ANOVA analysis tutorials">regression</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/PCA" title="principal component analysis tutorial">PCA</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/time+series" title="Time series">time series</a>, <a rel="nofollow" href="https://www.r-bloggers.com/search/trading" title="finance trading">trading</a>) and more...
<img width="1" alt="" src="http://feeds.feedburner.com/~r/RBloggers/~4/1B3w-W5oKVM" height="1"></a></div>