Skip to content

Commit

Permalink
content
Browse files Browse the repository at this point in the history
  • Loading branch information
tjbrailey committed Aug 2, 2020
1 parent 308a04a commit e688986
Show file tree
Hide file tree
Showing 16 changed files with 951 additions and 10 deletions.
2 changes: 1 addition & 1 deletion content/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ I have served as a research assistant for the Center for the Study of African Po

I am interested in political institutions, elections, secession, and conflict in developing democracies, with a particular focus in sub-Saharan Africa.

My CV can be found [here](/tjbrailey_resume_2020_academic.pdf).
My CV can be found [here](/tb.pdf).
8 changes: 4 additions & 4 deletions content/posts/niche_plots_I.Rmd
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "Ridiculously Niche Plots Episode I: Scaled Faceted Radar Plots with Colorful Text"
title: "Ridiculously Niche Plots Episode I: Scaled and Faceted Radar Plots"
author: "Tom Brailey"
date: "2020-06-17"
categories: ["R"]
Expand All @@ -10,7 +10,7 @@ Hello and welcome to the first episode in a series I like to call "Ridiculously

In today's episode, we will be looking at radar plots, specifically, radar plots faceted by country, more specifically, scaled faceted radar plots with axis labels that corresponds to its legend, which groups percentages of military equipment by the domain in which they operate, and where if that percentage is 0, the axis text is grayed-out.

To many of you I'm sure this sounds elementary, but, honestly, when I figured this out I felt a sense of achievement like no other. So, in the interesting of reliving that euphoric moment, here we go!
To many of you I'm sure this sounds elementary, but, honestly, when I figured this out I felt a sense of achievement like no other. So, in the interest of reliving that euphoric moment, here we go!

Firstly, I do some top-secret data cleaning.

Expand Down Expand Up @@ -208,10 +208,10 @@ p <-
grid.arrange(arrangeGrob(
grobs = my_list,
nrow = round(length(my_sub)/2, 0),
left = textGrob("X axis",
left = textGrob("Y axis",
gp = gpar(fontsize = 20),
rot = 90),
bottom = textGrob("Y axis",
bottom = textGrob("X axis",
gp = gpar(fontsize = 20),
vjust = -3),
top = textGrob("Big plot",
Expand Down
14 changes: 9 additions & 5 deletions content/posts/niche_plots_I.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "Ridiculously Niche Plots Episode I: Scaled Faceted Radar Plots with Colorful Text"
title: "Ridiculously Niche Plots Episode I: Scaled and Faceted Radar Plots"
author: "Tom Brailey"
date: "2020-06-17"
categories: ["R"]
Expand All @@ -19,15 +19,15 @@

<p>Hello and welcome to the first episode in a series I like to call “Ridiculously Niche Plots”! An intermittent series where I give a brief rundown of especially strange plots that I have spent hours trying to crack, in the hope that someone, somewhere, struggling to understand the ins and outs of gridExtra or who are hitting their head against a wall because ggplot2 is throwing out a horrifically labyrinthine error, might stumble on this article and have all of their questions answered. I have certainly spent many hours hoping for the same…</p>
<p>In today’s episode, we will be looking at radar plots, specifically, radar plots faceted by country, more specifically, scaled faceted radar plots with axis labels that corresponds to its legend, which groups percentages of military equipment by the domain in which they operate, and where if that percentage is 0, the axis text is grayed-out.</p>
<p>To many of you I’m sure this sounds elementary, but, honestly, when I figured this out I felt a sense of achievement like no other. So, in the interesting of reliving that euphoric moment, here we go!</p>
<p>To many of you I’m sure this sounds elementary, but, honestly, when I figured this out I felt a sense of achievement like no other. So, in the interest of reliving that euphoric moment, here we go!</p>
<p>Firstly, I do some top-secret data cleaning.</p>
<p></p>
<p>beep boop</p>
<p></p>
<p>Okay, so here’s what our data looks like:</p>
<pre class="r"><code>DT::datatable(tbl[1:20,])</code></pre>
<p><div id="htmlwidget-1" style="width:100%;height:auto;" class="datatables html-widget"></div>
<script type="application/json" data-for="htmlwidget-1">{"x":{"filter":"none","data":[["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"],["Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Albania","Albania","Albania","Albania","Albania","Albania","Albania","Algeria","Algeria","Algeria","Algeria","Algeria","Algeria"],[1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961,1961],["value 3","value 3","value 3","value 15","value 15","value 15","value 17","value 3","value 3","value 3","value 15","value 15","value 15","value 17","value 3","value 3","value 3","value 15","value 15","value 15"],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],["domain c","domain c","domain c","domain b","domain b","domain b","domain b","domain c","domain c","domain c","domain b","domain b","domain b","domain b","domain c","domain c","domain c","domain b","domain b","domain b"]],"container":"<table class=\"display\">\n <thead>\n <tr>\n <th> <\/th>\n <th>country<\/th>\n <th>year<\/th>\n <th>var_name<\/th>\n <th>unit_count<\/th>\n <th>domain<\/th>\n <\/tr>\n <\/thead>\n<\/table>","options":{"columnDefs":[{"className":"dt-right","targets":[2,4]},{"orderable":false,"targets":0}],"order":[],"autoWidth":false,"orderClasses":false}},"evals":[],"jsHooks":[]}</script>
<script type="application/json" data-for="htmlwidget-1">{"x":{"filter":"none","data":[["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20"],["Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan","Afghanistan"],[1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970,1970],["value 2","value 2","value 3","value 3","value 3","value 3","value 3","value 3","value 3","value 3","value 3","value 3","value 4","value 5","value 5","value 6","value 6","value 8","value 8","value 11"],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],["domain c","domain c","domain c","domain c","domain c","domain c","domain c","domain c","domain c","domain c","domain c","domain c","domain b","domain a","domain a","domain a","domain a","domain c","domain c","domain c"]],"container":"<table class=\"display\">\n <thead>\n <tr>\n <th> <\/th>\n <th>country<\/th>\n <th>year<\/th>\n <th>var_name<\/th>\n <th>unit_count<\/th>\n <th>domain<\/th>\n <\/tr>\n <\/thead>\n<\/table>","options":{"columnDefs":[{"className":"dt-right","targets":[2,4]},{"orderable":false,"targets":0}],"order":[],"autoWidth":false,"orderClasses":false}},"evals":[],"jsHooks":[]}</script>
Now we do a little bit of work to create functions and whatnot:</p>
<pre class="r"><code># This function gets all the legend information from a given ggplot object
get_legend &lt;-
Expand Down Expand Up @@ -118,10 +118,14 @@
}</code></pre>
<pre><code>## Warning: Factor `country` contains implicit NA, consider using
## `forcats::fct_explicit_na`</code></pre>
<pre><code>## Warning: Factor `domain` contains implicit NA, consider using
## `forcats::fct_explicit_na`</code></pre>
<pre><code>## Warning: Vectorized input to `element_text()` is not officially supported.
## Results may be unexpected or may change in future versions of ggplot2.</code></pre>
<pre><code>## Warning: Factor `country` contains implicit NA, consider using
## `forcats::fct_explicit_na`</code></pre>
<pre><code>## Warning: Factor `domain` contains implicit NA, consider using
## `forcats::fct_explicit_na`</code></pre>
<pre><code>## Warning: Vectorized input to `element_text()` is not officially supported.
## Results may be unexpected or may change in future versions of ggplot2.</code></pre>
<p>So now we have a list of ggplot objects that have all been scaled as if using the facet_grid(scales = “fixed”) argument. All we have left to do is neatly plot them together along with a single lengend rather than a legend for each plot.</p>
Expand All @@ -138,10 +142,10 @@
grid.arrange(arrangeGrob(
grobs = my_list,
nrow = round(length(my_sub)/2, 0),
left = textGrob(&quot;X axis&quot;,
left = textGrob(&quot;Y axis&quot;,
gp = gpar(fontsize = 20),
rot = 90),
bottom = textGrob(&quot;Y axis&quot;,
bottom = textGrob(&quot;X axis&quot;,
gp = gpar(fontsize = 20),
vjust = -3),
top = textGrob(&quot;Big plot&quot;,
Expand Down
52 changes: 52 additions & 0 deletions content/posts/niche_plots_II.Rmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: "Ridiculously Niche Plots Episode II: Vessel Range from Coastline in ArcGIS"
author: "Tom Brailey"
date: "2020-08-01"
categories: ["ArcGIS"]
tags: ["ArcGIS", "path distance"]
---


Hello and welcome to the second episode of Ridiculously Niche Plots! Today, we are moving away from R into the realm of ArcGIS. Arc is quite a bit different to R, and reproducing outputs can be a little complicated. While there is no code to show per se, I will run through the model which is laid out in a sort of flowchart format.

#### Context

This project was part of my work at cPASS, specifically, Andres Gannon's dissertation on military specialization. The genesis of plot occurred as follows. Say a country that has recently joined a military alliance and acquires a new military vessel, what can the range of that vessel tell us? For example, after joining NATO, Albania acquired a military vessel that had a range of 1850 nautical miles (roughly 3426 kilometers), a range that is clearly larger than the maritime boundaries that the ship would need to patrol. Of course, it makes sense for a ship to have a larger range than is needed, but we wanted to understand just how big that range was compared to the country's maritime boundaries, and whether a ship's range gave insight into the military alliance itself.

To do this, I needed to map which countries a ship with a range of 1850 nautical miles could reach. While this sounded simple to me in principal, I found this to be a far more challenging task. While it is easy to create a circle around Albania that is radius 1850 nautical miles, this is misleading as it assumes a ship can just travel in a straight line, and across land. So the question becomes, what does 1850 nautical miles look like when accounting for the presence of land?

Below, you will see the flowchart layout of the model used to create a map of Albania, it's maritime boundaries, and the vessel's range. For those familiar with ArcGIS, I apologize in advance for my poor object-naming scheme; this project had gone through many iterations and by the end I had given up on naming conventions. I have named each step in the model for ease of understanding.

![](/posts/niche_plots_II_files/Export Graphic.jpg)

1. This plot can be replicated using three shapefiles from the web. Firstly, eez_boundaries_v11.shp is a shapefile containing information on maritime boundaries for all countries. gadm36_0.shp is a shapefile of all countries. I use this to create gadm36_0_Select2_Project_Clip.shp, which I will explain later. These files are the foundations for our visualization.

2. We start by selecting just the maritime boundary for Albania.

3. We then project the shapefile into a projected coordinate system that preserves distance (given that out ultimate objective is to calculate the total traversable distance of Albania's military vessels). For that, we use a European equidistant conic projection.

4. Now, we create a buffer around the central point of Albania's maritime boundary. In essence, we are drawing a circle with a radius of 1850 nautical miles around the maritime boundary.

5. (+ also 10) Here is where it gets a bit complicated. gadm36_0_Select2_Project_Clip.shp is created by clipping the buffer made in step 4 with the shapefile of all countries, resulting in a shapefile that is all the land that exists within the buffer. ArcGIS can be a little temperamental, and I had to write a separate model to create this output to stop the main model from breaking inexplicably (steps 8, 9, and 10 create the output, but under a different name). Anyway, we take the buffer from step four, and essentially "erase" anything that is common between that and the land within the buffer. This means that we are left with only water regions within the buffer around Albania's maritime boundary.

6. We now convert the shapefile that contains all the water within the vessel's range into a raster file. When converting to raster, we are able to specify the size of each square that makes up the image -- for our purposes, we covert to kilometers.

7. On opening the attributes table of the raster file, we see that each cell that makes up the image has a different value. In order to run our model later on, we need each cell to equal 1. Running "reclassify" in our case turns all values that are not equal to 1 to equal 1. The raster file is now ready to be put into the path distance model

8. We now take the shapefile of all countries and remove Antarctica. This has just become a weird habit of mine...

9. It is essential that all of our input files are in the same projection, otherwise our results will be completely off. Here I convert the shapefile to the European equidistant conic projection mentioned in step 3.

10. Here, I subset the shapefile of all countries to just those that fall within the buffer created in step 4. Because of ArcGIS's quirks, I had to rename this file and manually read it in for it to be used for step 5.

11. Now I subset the global shapefile to just include Albania. This is for both visual purposes (I want to be able to highlight where Albania is in reference to the rest of Europe) and also in order to run the main model.

12. It is time to run the path distance model. The model requires two inputs, the starting point (the Albania shapefile, from step 11) and the cost raster (the output from step 7). The path distance model calculates distances from Albania while also accounting for the presence of obstacles, however, in doing so, it calculates distances that are beyond 1850 nautical miles (e.g. travelling from Albania to Norway via Portugal is within the buffer, but is more than 1850 nautical miles). As such, the final step is to filter values that are beyond the actual range of the ship. Doing so leaves us with the traversable distance of the ship, as denoted by the blue shaded area in the image below.

In Arc, there are a lot of manual, and thus not really reproducible, edits you must make in order for the map to be considered publication-worthy. For example, I spent time coloring in the different shapefiles for maximum effect and clarity, adding a title, legend, and map information, and rescaling the plot to make it as clear as possible. The final product is below:

![](/posts/niche_plots_II_files/albania_vessel_range.png)

Quite niche indeed! This project was deceptively complicated, and more time was spent conceptualizing the problem than actually running the model. Nonetheless, it was a super interesting and enjoyable process, and I think the final product is pretty cool!

That concludes the second episode of Niche Plots. Who knows what kind of weird things I will be plotting in the future...
Loading

0 comments on commit e688986

Please sign in to comment.