Danny became the [first hurricane of the 2015 Season](http://www.accuweather.com/en/weather-news/atlantic-gives-birth-to-tropical-depression-four-danny/51857239), so it’s a good time to revisit how one might be able to track them with R.
We’ll pull track data from [Unisys](http://weather.unisys.com/hurricane/atlantic/2015/index.php) and just look at Danny, but it should be easy to extrapolate from the code.
For this visualization, we’ll use [leaflet](http://rstudio.github.io/leaflet/) since it’s all the rage and makes the plots interactive without any real work (thanks to the very real work by the HTML Widgets folks and the Leaflet.JS folks).
Let’s get the library calls out of the way:
library(leaflet) library(stringi) library(htmltools) library(RColorBrewer)
Now, we’ll get the tracks:
danny <- readLines("http://weather.unisys.com/hurricane/atlantic/2015/DANNY/track.dat")
Why aren’t we using `read.csv` or `read.table` directly, you ask? Well, the data is in a _really_ ugly format thanks to the spaces in the `STATUS` column and two prefix lines:
Date: 18-20 AUG 2015 Hurricane-1 DANNY ADV LAT LON TIME WIND PR STAT 1 10.60 -36.50 08/18/15Z 30 1009 TROPICAL DEPRESSION 2 10.90 -37.50 08/18/21Z - - TROPICAL DEPRESSION 3 11.20 -38.80 08/19/03Z - - TROPICAL DEPRESSION 4 11.30 -40.20 08/19/09Z - - TROPICAL DEPRESSION 5 11.20 -41.10 08/19/15Z - - TROPICAL DEPRESSION 6 11.50 -42.00 08/19/21Z - - TROPICAL DEPRESSION 7 12.10 -42.70 08/20/03Z - - TROPICAL DEPRESSION 8 12.20 -43.70 08/20/09Z - - TROPICAL DEPRESSION 9 12.50 -44.80 08/20/15Z - - TROPICAL DEPRESSION +12 13.10 -46.00 08/21/00Z 70 - HURRICANE-1 +24 14.00 -47.60 08/21/12Z 75 - HURRICANE-1 +36 14.70 -49.40 08/22/00Z 75 - HURRICANE-1 +48 15.20 -51.50 08/22/12Z 70 - HURRICANE-1 +72 16.00 -56.40 08/23/12Z 65 - HURRICANE-1 +96 16.90 -61.70 08/24/12Z 65 - HURRICANE-1 +120 18.00 -66.60 08/25/12Z 55 - TROPICAL STORM
But, we can put that into shape pretty easily, using `gsub` to make it easier to read everything with `read.table` and we just skip over the first two lines (we’d use them if we were doing other things with more of the data).
danny_dat <- read.table(textConnection(gsub("TROPICAL ", "TROPICAL_", danny[3:length(danny)])), header=TRUE, stringsAsFactors=FALSE)
Now, let’s make the data a bit prettier to work with:
# make storm type names prettier danny_dat$STAT <- stri_trans_totitle(gsub("_", " ", danny_dat$STAT)) # make column names prettier colnames(danny_dat) <- c("advisory", "lat", "lon", "time", "wind_speed", "pressure", "status")
Those steps weren’t absolutely necessary, but why do something half-baked (unless it’s chocolate chip cookies)?
Let’s pick better colors than Unisys did. We’ll use a color-blind safe palette from Color Brewer:
danny_dat$color <- as.character(factor(danny_dat$status, levels=c("Tropical Depression", "Tropical Storm", "Hurricane-1", "Hurricane-2", "Hurricane-3", "Hurricane-4", "Hurricane-5"), labels=rev(brewer.pal(7, "YlOrBr"))))
And, now for the map! We’ll make lines for the path that was already traced by Danny, then make interactive points for the forecast locations from the advisory data:
last_advisory <- tail(which(grepl("^[[:digit:]]+$", danny_dat$advisory)), 1) # draw the map leaflet() %>% addTiles() %>% addPolylines(data=danny_dat[1:last_advisory,], ~lon, ~lat, color=~color) -> tmp_map if (last_advisory < nrow(danny_dat)) { tmp_map <- tmp_map %>% addCircles(data=danny_dat[last_advisory:nrow(danny_dat),], ~lon, ~lat, color=~color, fill=~color, radius=25000, popup=~sprintf("<b>Advisory forecast for +%sh (%s)</b><hr noshade size='1'/> Position: %3.2f, %3.2f<br/> Expected strength: <span style='color:%s'><strong>%s</strong></span><br/> Forecast wind: %s (knots)<br/>Forecast pressure: %s", htmlEscape(advisory), htmlEscape(time), htmlEscape(lon), htmlEscape(lat), htmlEscape(color), htmlEscape(status), htmlEscape(wind_speed), htmlEscape(pressure))) } html_print(tmp_map)
Click on one of the circles to see the popup.
The entire source code is in [this gist](https://gist.github.com/hrbrmstr/e3253ddd353f1a489bb4) and, provided you have the proper packages installed, you can run this at any time with:
devtools::source_gist("e3253ddd353f1a489bb4", sha1="00074e03e92c48c470dc182f67c91ccac612107e")
The use of the `sha1` hash parameter will help ensure you aren’t being asked to run a potentially modified & harmful gist, but you should visit the gist first to make sure I’m not messing with you (which, I’m not).
If you riff off of this or have suggestions for improvement, drop a note here or in the gist comments.
4 Comments
Hey, I did the map on R using your tutorial and now I want to embed it in my college page. The thing is I’m not really skilled with Html. I was wondering if you could give me a little help on that; I’ll appreciate it.
you can use
htmlwidgets::saveWidget
to save the “map” as an HTML file and then use something like this https://gist.github.com/hrbrmstr/06977865d6a25213d122 to embed it.very nice idea and visualization! for some reason I receive in the plot only a long line for all the data, without the circles and the popup text when you hover above the points.
Thx for checking the post out and letting me know about the issue. The code & gist are both updated to account for an unexpected format change.
One Trackback/Pingback
[…] Track Hurricane Danny (Interactively) with R + leaflet […]