Political machinations are a tad insane in the U.S. these days & I regularly hit up @ProPublica & @GovTrack sites (& sub to the GovTrack e-mail updates) as I try to be an informed citizen, especially since I’ve got a Senator and Representative who seem to be in the sway of 🍊.
I’ve always appreciated the ProPublica and GovTrack cartograms as they present a great deal of information in a compact space (especially the House versions). Something nudged me into starting an R package to let folks create them in R (mainly with
ggplot2 but an
htmlwidget version is planned), which I’ve dubbed
voteogram package, you can:
- pull ProPublica roll call vote data for the 101st Congress up through today (via
- plot ProPublica-esque Senate roll call vote cartograms
- plot ProPublica-esque House roll call vote cartograms
- plot GovTrack-esque House roll call vote cartograms
GovTrack uses — what I’ve seen @thosjleeper refer to as — a “parliamentary plot” for their version of the Senate roll call cartogram and sir Leeper already has that type of plot covered in
ggparliament, so I’ve just focused on the other ones here.
You need data for these cartogram generation functions and you can specify your own populated data frame (the needed columns are in the manual pages for the cartogram plotters). However, you’ll likely want to plot existing data that others have tallied and ProPublica makes that super simple since each vote is in a standalone JSON file. All you have to do is specify whether you want the roll call vote for the
senate, the Congress number (current one is 115), the session number (current one is 1) and the roll call vote number.
For example, we can see all the
idiots Representatives who voted, recently, to kill people repeal the ACA with the following function call:
(h256 <- roll_call("house", 115, 1, 256)) ## 115th Congress / Session: 1 / House Roll Call: 256 / May 4, 2017 ## ## American Health Care Act ## ## Result: Passed str(h256, max.level = 1) ## List of 29 ## $ vote_id : chr "H_115_1_256" ## $ chamber : chr "House" ## $ year : int 2017 ## $ congress : chr "115" ## $ session : chr "1" ## $ roll_call : int 256 ## $ needed_to_pass : int 216 ## $ date_of_vote : chr "May 4, 2017" ## $ time_of_vote : chr "02:18 PM" ## $ result : chr "Passed" ## $ vote_type : chr "RECORDED VOTE" ## $ question : chr "On Passage" ## $ description : chr "American Health Care Act" ## $ nyt_title : chr "On Passage" ## $ total_yes : int 217 ## $ total_no : int 213 ## $ total_not_voting : int 1 ## $ gop_yes : int 217 ## $ gop_no : int 20 ## $ gop_not_voting : int 1 ## $ dem_yes : int 0 ## $ dem_no : int 193 ## $ dem_not_voting : int 0 ## $ ind_yes : int 0 ## $ ind_no : int 0 ## $ ind_not_voting : int 0 ## $ dem_majority_position: chr "No" ## $ gop_majority_position: chr "Yes" ## $ votes :Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 435 obs. of 11 variables: ## - attr(*, "class")= chr [1:2] "pprc" "list"
As you can see, it has a custom
$votes. You can go to town with just that information, making bar charts or tracking individual Congress-critter votes.
Do your best to cache this data as you retrieve it. ProPublica is a non-profit and the JSON files are on AWS. While there’s a certain number of free bits of bandwidth-per-month allotted buy Amazon’s S3 service, best to make sure you’re not tipping them over on any given month. Plus, the vote data doesn’t change once it’s recorded. Consider donating to them if you decided to always grab fresh copies.
fortify function for this object (it’s classed
pprc) so you can pass it right into
ggplot() for use or pipe it into a
dplyr chain for aggregation & filtering.
With the data in hand, we can make some cartograms (the real purpose of the package). I riffed off the ProPublica colors (and haven’t fully finished copying them yet as I need to search for 2 more categories of Independent voting colors) but you can replace them with anything you want. Just reset the scale and use the names in the exposed color value vectors.
There’s also a
theme_voteogram() which is designed to augment any base theme (like
hrbrthemes::theme_ipsum_rc()) (it’s much like
Here’s the ProPublica view for that particular vote:
house_carto(rep) + labs(x=NULL, y=NULL, title="House Vote 256 - Passes American Health Care Act,\nRepealing Obamacare") + theme_ipsum_rc(plot_title_size = 24) + theme_voteogram()
house_carto() function defaults to the ProPublica cartogram, but you can easily change that:
house_carto(rep, "gt") + labs(x=NULL, y=NULL, title="House Vote 256 - Passes American Health Care Act,\nRepealing Obamacare") + theme_ipsum_rc(plot_title_size = 24) + theme_voteogram()
senate_carto() function only has the ProPublica-esque cartogram available and works pretty much the same way after getting the Senate vote data:
sen <- roll_call("senate", 115, 1, 110) senate_carto(sen) + labs(title="Senate Vote 110 - Invokes Cloture on Neil Gorsuch Nomination") + theme_ipsum_rc(plot_title_size = 24) + theme_voteogram()