Browse Source

Very rough first try to show all tornado traces

master
Nathan Bergey 5 years ago
parent
commit
4ff55867f0
  1. 1
      .gitignore
  2. 12
      Makefile
  3. 14
      Pipfile
  4. 17
      README.markdown
  5. 3
      README.md
  6. BIN
      tornados_us.png
  7. 115
      tornados_us.py

1
.gitignore

@ -94,3 +94,4 @@ ENV/
# Rope project settings
.ropeproject
*.csv

12
Makefile

@ -0,0 +1,12 @@
all: tornados_us.png
1950-2017_actual_tornadoes.csv:
curl -O https://www.spc.noaa.gov/wcm/data/1950-2017_actual_tornadoes.csv
%.png: %.py 1950-2017_actual_tornadoes.csv
pipenv run python $^
clean:
rm -f *.png
.PHONY: all clean

14
Pipfile

@ -0,0 +1,14 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
matplotlib = "*"
cartopy = "*"
scipy = "*"
[requires]
python_version = "3.7"

17
README.markdown

@ -0,0 +1,17 @@
Map of tornado historic tornado traces
======================================
Data from https://www.spc.noaa.gov/wcm
## All US tornados 1950-20017
![map of US with traces of tornado paths](tornados_us.png)
### Dev
Using pipenv
$ pipenv install
$ make

3
README.md

@ -1,3 +0,0 @@
# tornado-map
Map of tornado historic tornado traces

BIN
tornados_us.png

After

Width: 2048  |  Height: 1536  |  Size: 865 KiB

115
tornados_us.py

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
import csv
from dataclasses import dataclass
from datetime import datetime
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import cartopy.feature as cfeature
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from cartopy import geodesic
import shapely.geometry as sgeom
proj = ccrs.AlbersEqualArea(
central_longitude=-95,
central_latitude=40,
)
water_blue = "#7ebfd4"
def phys(name, resolv):
return cfeature.NaturalEarthFeature('physical', name, resolv, facecolor="none")
def cultural(name, resolv):
return cfeature.NaturalEarthFeature('cultural', name, resolv, facecolor="none")
land = phys("land", "50m")
rivers = phys("rivers_lake_centerlines", "50m")
lakes = phys("lakes", "50m")
countries = cultural("admin_0_countries", "50m")
states = cultural("admin_1_states_provinces_lines", "50m")
@dataclass
class Tornado:
om: str
yr: str
mo: str
dy: str
date: str
time: str
tz: str
st: str
stf: str
stn: str
mag: str
inj: str
fat: str
loss: str
closs: str
slat: str
slon: str
elat: str
elon: str
len: str
wid: str
ns: str
sn: str
sg: str
f1: str
f2: str
f3: str
f4: str
fc: str
def __post_init__(self):
self.id = int(self.om)
self.dt = datetime.strptime(self.date, "%Y-%m-%d")
self.slon = float(self.slon)
self.slat = float(self.slat)
self.elon = float(self.elon)
self.elat = float(self.elat)
def __repr__(self):
return "<tornado {id} {date}>".format(id=self.id, date=self.dt)
def read_data():
tornados = []
with open("1950-2017_actual_tornadoes.csv", newline='') as csvfile:
reader = csv.DictReader(csvfile)
for i, row in enumerate(reader):
tornados.append(Tornado(**row))
return tornados
def draw_map(data):
fig = plt.figure(frameon=False)
ax = fig.add_subplot(111, projection=proj)
ax.background_patch.set_facecolor(water_blue)
ax.set_extent([-125, -65, 20, 50], ccrs.Geodetic())
ax.add_feature(land, facecolor="#f0f0f0")
ax.add_feature(rivers, edgecolor=water_blue)
ax.add_feature(lakes, facecolor=water_blue)
ax.add_feature(countries, edgecolor="grey", linewidth=0.2, alpha=0.6, dashes='--')
ax.add_feature(states, edgecolor="grey", linewidth=0.2, alpha=0.4, dashes='--')
for i, t in enumerate(data):
print(i)
if t.elon < 0:
ax.plot([t.slon, t.elon], [t.slat, t.elat], 'r', lw=0.3, transform=ccrs.Geodetic())
else:
ax.plot([t.slon, t.slon], [t.slat, t.slat], 'r', lw=0.3, transform=ccrs.Geodetic())
fig.tight_layout()
plt.savefig("tornados_us.png", dpi=320)
if __name__ == '__main__':
ts = read_data()
draw_map(ts)
Loading…
Cancel
Save