# -*- coding: utf-8 -*- import csv from dataclasses import dataclass, field from datetime import datetime from typing import List 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=35, ) 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) self.mag = int(self.mag) def __repr__(self): return "".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(f_unknown, f_zero, f_one, f_two, f_three, f_four, f_five): fig = plt.figure(frameon=False, figsize=(12, 7.1)) ax = fig.add_axes([0, 0, 1, 0.95], projection=proj) ax.background_patch.set_facecolor(water_blue) ax.set_extent([-122, -65, 21, 50], ccrs.Geodetic()) ax.add_feature(land, facecolor="#f0f0f0") 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='--') ax.coastlines(resolution='50m', color="#55aacc", linewidth=0.2) geodetic = ccrs.Geodetic() ax.plot(f_unknown.lons, f_unknown.lats, 'k', lw=0.2, alpha=0.7, label="Unknown", transform=geodetic) ax.plot(f_zero.lons, f_zero.lats, '#ffbb00', lw=0.2, alpha=1, label="F0", transform=geodetic) ax.plot(f_one.lons, f_one.lats, '#ff7700', lw=0.3, alpha=1, label="F1", transform=geodetic) ax.plot(f_two.lons, f_two.lats, '#ff4400', lw=0.4, alpha=0.8, label="F2", transform=geodetic) ax.plot(f_three.lons, f_three.lats, '#ff1100', lw=0.5, alpha=0.8, label="F3", transform=geodetic) ax.plot(f_four.lons, f_four.lats, 'r', lw=0.6, alpha=0.8, label="F4", transform=geodetic) ax.plot(f_five.lons, f_five.lats, 'r', lw=0.8, alpha=0.7, label="F5", transform=geodetic) ax.axis('off') plt.title(" US Tornados 1950-2017", loc='left') ax.text(0, 0.01, " data from https://www.spc.noaa.gov/wcm/", transform=ax.transAxes, fontsize=6) plt.legend(loc=4, title="Intensity", fontsize='small') plt.savefig("tornados_us.png", dpi=190) @dataclass class Fmag: lons: List[int] = field(default_factory=list) lats: List[int] = field(default_factory=list) def append(collection, tornado): collection.lons.append(tornado.slon) collection.lats.append(tornado.slat) if tornado.elon < 0: collection.lons.append(tornado.elon) collection.lats.append(tornado.elat) else: collection.lons.append(tornado.slon) collection.lats.append(tornado.slat) collection.lons.append(None) collection.lats.append(None) if __name__ == '__main__': ts = read_data() f_unknown = Fmag() f_zero = Fmag() f_one = Fmag() f_two = Fmag() f_three = Fmag() f_four = Fmag() f_five = Fmag() for t in ts: if t.mag == 0: append(f_zero, t) elif t.mag == 1: append(f_one, t) elif t.mag == 2: append(f_two, t) elif t.mag == 3: append(f_three, t) elif t.mag == 4: append(f_four, t) elif t.mag == 5: append(f_five, t) else: append(f_unknown, t) draw_map(f_unknown, f_zero, f_one, f_two, f_three, f_four, f_five)