Silently load necessary packages:

“dplyr”,“gganimate”,“RColorBrewer”,“ggplot2”,“ggrepel”,“gifski”

Get the data

The data is downloaded from https://www.spc.noaa.gov/wcm/#data The name of the file is 1950-2017_actual_tornadoes.csv

filepath <- "https://www.spc.noaa.gov/wcm/data/1950-2017_actual_tornadoes.csv"
if(!exists("rawdatsa.csv"))  download.file(filepath, destfile = "rawdata.csv", method="curl")
readfile <- read.csv("rawdata.csv")

Light processing of data

tornadoes <- rename(readfile, year=yr, magnitude=mag)

countAll <- as.data.frame(table(tornadoes$year))
countAll <- rename(countAll, year = Var1, countAll = Freq)


# Select with just the larger Tornadoes:
# Uses Fujita scale or Enhanced Fujita scale after 2007 
# Scales are (upper bounds for 0,1,2,3,4,5, winds in mph) 
# Fujita          [73,112,157,208,260,+inf] 
# Enhanced Fujita [85,110,135,165,200,+inf]
# F and EF align almost exactly at magnitude==2, so let's use that for our limit.   
bigTornadoes <- filter(tornadoes, magnitude>=2)
countBig <- as.data.frame(table(bigTornadoes$year))
countBig <- rename(countBig, year = Var1, countBig = Freq)

# Make a table of all tornadoes / big tornadoes counts: 
counts <- left_join(countAll, countBig, by="year")
counts$year <-as.numeric(as.character(counts$year))
head(counts)
##   year countAll countBig
## 1 1950      201       99
## 2 1951      260      111
## 3 1952      240      126
## 4 1953      421      196
## 5 1954      550      235
## 6 1955      591      204

Plot number of tornadoes per year in the US (1950 - 2018)

Here is an animated plot, with the code:

# Plot of number of tornadoes / big tornadoes
gBothAnim <- ggplot(data=counts, aes(x=year, y=countAll, label=year)) + 
  geom_area(fill='#FFFF0044') +
  geom_point(aes(color=countAll)) +
  geom_line(aes(color=countAll), size=1) +
  geom_area(aes(y=countBig),fill='#F9A602') +
  geom_line(aes(y=countBig, color=countBig), size=1) +
  geom_point(aes(y=countBig, color=countBig)) +
  scale_color_gradient(name="Count",low="blue", high="red") +
  geom_text_repel(data=. %>% filter(year==max(year)), mapping = aes(x=year, y=countAll, label="All Tornadoes"), size=5) + 
  geom_text_repel(data=. %>% filter(year==max(year)), mapping = aes(x=year, y=countBig, label="Big Tornadoes"), size=5)+
  theme(plot.title = element_text(hjust = 0.5, size=14, face="bold"), plot.subtitle = element_text(hjust = 0.5)) +
  labs(y="Yearly Tornado Count", x="Year", title="Number of Tornadoes per Year, USA 1950-2018", 
       caption = "Data source = https://www.spc.noaa.gov/wcm/#data. \n All Tornadoes = Category 0-5; Big tornadoes = Category ≥2")+
    transition_reveal(year)
animate(gBothAnim, end_pause=30,width=800,height=500)

Just in case

If the animation fails, here’s the static plot: