Stata graphs: Hex maps of the 2020 USA Presidential elections
By: Asjad Naqvi
Tags: 2020 Presidential Race, Hex Map, USA, Stata, Color Scheme

In this guide we will learn how to make the following hex map in Stata using the recent 2020 United States Presidential elections data:

This guide is more limited in its application than other guides since it makes use of the maptile package, a wrapper of the spmap package that I have discussed before here and here. Michael Stepner, the creator of maptile has also uploaded the hex map of the US states here including a host of other geographic boundaries as well. Since the number of maps are limited, the application is also limited to the templates provided. One can, theoretically, covert and generate other hex maps for Stata as well but this requires some effort. Since this program was last updated three years ago, customization options for hex plots are also limited, especially the ability to change labels and outlines of hex tiles. Similarly legend features are limited but the program does allow one to call in the standard twoway graph options for some flexibility with map customization.

The maptile package also makes use of the spmap color schemes. But here we will also learn how to incorporate custom color schemes from Ben Jann’s colorpalette package, which opens up endless possibilities. spmap schemes do provide a decent range but they are usually limited by the number of cut-offs one can define. See my guide here for an intro to color customization.

DISCLAIMER: This guide is meant for educational purposes only and does not reflect the most accurate election figures. The election results are still coming in at the time of the writing this guide, thus the numbers will most likely be outdated once this is published. I have provided a basic dataset on my Github and I will update it eventually but please check online for the latest information.

Getting started

As mentioned in all the previous guides, I follow the following folder structure to maintain the workflow:

While in recent guides, I have put little emphasis on the folders, they are extremely helpful in organizing and sorting the various files that are used and generated by Stata. For example, for this guide, the raw data is in the raw folder, the dofiles in the dofiles folder, and the graphs in ./graphs/guide9 folder.

For all my guides, I use the cleanplots scheme:

net install cleanplots, from(" https://tdmize.github.io/data/cleanplots ") set scheme cleanplots, perm

Other good options are plotplain. Check this guide on a detailed intro.

Set the default font to Arial Narrow:

graph set window fontface "Arial Narrow"

For a detail on how to use other fonts see this guide.

Install the following Stata packages:

ssc install spmap, replace

ssc install maptile, replace

ssc install colorpalette, replace

ssc install colrspace, replace

Making the plots

I have uploaded the data on my Github, which can be downloaded direct in Stata as follows:



import delimited using " *** get the dataimport delimited using " https://raw.githubusercontent.com/asjadnaqvi/COVID19-Stata-Tutorials/master/raw/us_elections.csv ", clear

In the dataset, the variables are the state name, the two letter state code, electoral votes (EV) of each state. At the time of writing this, three states (Alaska, Georgia, North Carolina) were still not called. This part of the guide will be updated later once the figures are released. The last three variables are share of votes won by Democrats, Republicans, and Other parties.

From the data, we generate three variables of interest:

*** generate the variables gen party = dem > rep

replace party = party + 1

tab party lab de party 1 "Republican" 2 "Democrat"

lab val party party gen winvote = .

replace winvote = -1 * rep * 100 if rep > dem

replace winvote = dem * 100 if dem > rep

lab var winvote "% votes of winning party"

gen margin = (dem - rep) * 100

lab var margin "Winning margin"

The first variable party indicates which party won. Plus one added just to make it neutral.

The second variable, winvote , shows the share of votes by the winning party. For Democrats this is in the positive range and for Republicans in the negative range. The ranges allow us to use diverging color schemes to distinguish the parties. The negative values can be corrected by over-riding the labels of the legends.

The third variable, margin , shows the percentage point difference of the winning party. This variable indicates how close the race was in each state.

Next get the hex map for the US:

This command will automatically prepare all the files necessary. Let’s draw a basic plot of winners at the state level:

maptile party, geo(statehex) fcolor(red%60 midblue%60) ///

twopt( ///

title("{fontface Arial Bold: USA Presidential Elections 2020}") ///

note("Last updated: 8 November 2020, 2100 EST", size(tiny)) ///

legend(lab(2 "Republican") lab(3 "Democrat")) ///

)

Note the geo option defines which map to utilize. A normal map can also be used here. See here for other available maps. The colors red and blue are a bit subdued by using the %60 which increases their transparency. Also note that the title , legend , and note are called in using the standard Stata twoway options.

In the code above, I am also using multiple fonts. One can use any font in Stata graphs, and I have covered this in a previous guide.

Legend order is slightly messed up since we start with 2 as the label point. Maptile is designed for mostly continuous data, and therefore dealing with discrete data is not so straightforward but the above code works. From this code we get this plot:

The graph above is a bit misleading since state sizes are not proportional. This heterogeneity is represented by Electoral Votes (EVs) that are higher for larger states, for example, California (VA) is 55 EVs, while a small state like Delaware (DE) is only 3 EVs. Since we cannot modify the sizes or names of the cells, an easy trick is to add this information in the map as follows:

summ ev if dem > rep

local seatsDEM = `r(sum)' summ ev if rep > dem

local seatsREP = `r(sum)' maptile party, geo(statehex) fcolor(red%60 midblue%60) ///

twopt( ///

title("{fontface Arial Bold: USA Presidential Elections 2020}") ///

subtitle("Electoral votes: Democrats `seatsDEM', Republicans `seatsREP'") ///

note("Last updated: 8 November 2020, 2100 EST", size(tiny)) ///

legend(lab(2 "Republican") lab(3 "Democrat")) ///

)

which gives us the following information:

As the results come in the subtitle will automatically get updated. For the US, 270 EVs are necessary to win the election.

We can also look at the share of votes of the winning party:

summ winvote, d maptile winvote, geo(statehex) fcolor(RdBu) cutvalues(-75 -70 -65 -60 -50 0 50 60 70 100) legf(%9.0f) ///

twopt(title("{fontface Merriweather Bold: USA Presidential Elections 2020 - % votes by winning party}") ///

note("Last updated: 8 November 2020, 2100 EST", size(tiny)) ///

legend(size(*0.7)))

Since the variable winvote , generated earlier goes from the negative to the positive range, we use the diverging Red-Blue scheme fcolor(RdBu) , and based on the summary of the variable, manually define the cut-offs such that the negative ranges are equal in number to the positive ranges. This ensures that Republicans remain Red, and Democrats remain Blue:

This figure paints a slightly better picture of the elections that a binary winner-loser map. Here we can see that the legend also adds extra entries for the last values defined in the cut-offs. This is probably a bug in the program.

To make this graph slightly neater, we make two changes. First we push a custom color palette onto this map, and second we fix the legend labels so that parties are not defined as positive or negative:

colorpalette HCL bluered2, n(12) reverse nograph

local colors `r(p)' maptile win, geo(statehex) fcolor("`"`colors'"'") cutvalues(-80 -70 -65 -60 -50 0 50 60 70 100) legf(%9.0f) /// // cutp(party) cutv(1 2) nq(10)

twopt(title("{fontface Arial Bold: USA Presidential Elections 2020}") ///

subtitle("Share of votes by winning party") ///

note("Last updated: 8 November 2020, 2100 EST", size(tiny)) ///

legend(size(*0.7)) ///

legend( ///

lab(2 "Republican") ///

lab(3 "70 - 80") ///

lab(4 "65 - 70") ///

lab(5 "60 - 65") ///

lab(6 "50 - 60") ///

lab(7 "0 - 50") ///

lab(8 "0 - 50") ///

lab(9 "50 - 60") ///

lab(10 "60 - 70") ///

lab(11 "70 - 100") ///

lab(12 "Democrat") ///

) ///

)

Here note the use of double quotations `"`"`colors’"’" in the use of local colors for the maptile. Again this is probably a bug, but this quick fix allows us push the custom color scheme on to the hex map.

All the labels are also manually cleaned, which is something I would not deal with on a regular basis. If you have read my earlier guides, I am all about automation of outputs.

As one can see from the code above, the last and the first values of the legend have been replaced by the name of the parties, which gives it a neater look as seen in the figure below:

Another interesting graph we can generate from the data is the percentage point lead of the winning party. This just shows how close (or not) the elections were in certain states. For example according the data, at the time of writing this guide, Democrats had 47.9% votes and Republicans 51.2% vote in Florida (FL). Thus the percentage point lead in FL is just 3.3%.

We can generate this graph as follows using the margin variable we generated above:

colorpalette HCL bluered2, n(12) reverse nograph

return list

local colors `r(p)' maptile margin, geo(statehex) fcolor("`"`colors'"'") cutvalues(-50(10)30 35 40) legf(%9.0f) ///

twopt( ///

title("{fontface Arial Bold: USA Presidential Elections 2020}") ///

subtitle("Percentage point difference by states") ///

note("Last updated: 8 November 2020, 2100 EST", size(tiny)) ///

legend(size(*0.5)) ///

legend( ///

lab(2 "Republican") ///

lab(3 "40 - 50") ///

lab(4 "30 - 40") ///

lab(5 "20 - 30") ///

lab(6 "10 - 20") ///

lab(7 "0 - 10") ///

lab(8 "0 - 10") ///

lab(9 "10 - 20") ///

lab(10 "20 - 30") ///

lab(11 "30 - 35") ///

lab(12 "35 - 40") ///

lab(13 "Democrat") ///

) ///

)

which gives us this figure:

Here we can see that the lighter color states have close elections, while darker colors are the clear winners. Wyoming (WY) is overwhelmingly Republican, while Vermont (VT) is clearly Democrat.

Again, please update the numbers as they come in for more accurate and recent graphs. Hope you found this Stata guide useful. Please write if you have any questions, comments, or used it to produce some other cool maps.

About the author

I am an economist by profession and I have been using Stata since 2003. I am currently based in Vienna, Austria where I work at the Vienna University of Economics and Business (WU) and at the International Institute for Applied Systems Analysis (IIASA). You can find my research work on ResearchGate and Google Scholar, and Stata code repository on GitHub. You can follow my COVID-19 related Stata visualizations on my Twitter. I am also featured on the Stata COVID-19 webpage in the visualization and graphics section.

You can connect with me via Medium, Twitter, LinkedIn or simply via email: asjadnaqvi@gmail.com.

My Medium blog for Stata stuff here: The Stata Guide where new awesome content is released regularly. Clap, and/or follow if you like these guides!