Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Plot animation of spread of COVID 19
'''
Download data from github: https://github.com/CSSEGISandData/COVID-19
Place this file in
COVID-19/csse_covid_19_data/csse_covid_19_time_series/plotme.py
REQUIRES:
matplotlib
numpy
pillow
TO RUN:
python plotme.py
'''
from pylab import *
from numpy import *
import glob
import csv
import os.path
import os
covid = {}
n_day = 0
for fn in glob.glob('*.csv'):
dat = list(csv.reader(open(fn)))
#dates = [d for d in dat[0][4:] + dat[0][4:] + [dat[0][-1]] * 10]
dates = [d for d in dat[0][4:]]
typ = fn[:-4].split('-')[-1]
for l in dat[1:]:
city = l[0] + '//', l[1]
lat = float(l[2])
lon = float(l[3])
dat = list(map(float, l[4:]))
if city not in covid:
covid[city] = {}
covid[city][typ] = dat
covid[city]['lat'] = lat
covid[city]['lon'] = lon
if len(dat) > n_day:
n_day = len(dat)
world = []
for ll in open('world.dat.txt').readlines():
ll = ll.strip()
if ll:
lon, lat = map(float, ll.split())
world.append((lat, lon))
else:
world.append((nan, nan))
world = array(world)
DEG = pi/180
theta = arange(361) * DEG
circ = [cos(theta), sin(theta)]
def getr(n):
return sqrt(n/pi)/5
def plot_day(day, png):
close('all')
figure(figsize=(12, 6))
title(dates[day])
axis('equal')
xlim(-180, 180)
ylim(-90, 90)
xticks([])
yticks([])
plot(world[:,1], world[:,0], 'k-', linewidth=.5)
for city in covid:
if covid[city]['Confirmed'][day] > 0:
plot(covid[city]['lon'], covid[city]['lat'], 'k.')
if covid[city]['Deaths'][day] > 0:
plot(covid[city]['lon'], covid[city]['lat'], 'r.')
for city in covid:
c = covid[city]
confirmed = getr(c['Confirmed'][day])
fill(c['lon'] + circ[0] * confirmed, c['lat'] + circ[1] * confirmed, 'k-', alpha=.3)
for city in covid:
c = covid[city]
deaths = getr(c['Deaths'][day])
fill(c['lon'] + circ[0] * deaths, c['lat'] + circ[1] * deaths, 'k-', color='r', alpha=1)
for city in covid:
c = covid[city]
recovered = getr(c['Recovered'][day])
fill(c['lon'] + circ[0] * recovered, c['lat'] + circ[1] * recovered, color='g', alpha=.3)
# show(); here
#### legend
fill(-180 + 25 * circ[0], -40 + 25 * circ[1], color='k', alpha=.3)
fill(-180 + 5 * circ[0], -40 + 5 * circ[1], color='r', alpha=1)
fill(-180 + 15 * circ[0], -40 + 15 * circ[1], color='g', alpha=.3)
text(-175, -15, 'Confirmed')
text(-175, -30, 'Recovered')
text(-175, -40, 'Dead')
savefig(png)
print ('wrote', png)
if not os.path.exists('images'):
os.mkdir('images')
for day in range(n_day):
png = 'images/%03d.png' % day
if day < n_day - 1 and os.path.exists(png):
continue
plot_day(day, png)
for i in range(30):
png = f'images/{n_day+i+1:03d}.png'
plot(i, -89, 'k,')
savefig(png)
print ('wrote', png)
### convert images to GIF
import PIL.Image as Image
pngs = glob.glob('images/*.png')
pngs.sort()
gif = 'images.gif'
imgs = []
for png in pngs:
imgs.append(Image.open(png))
print(imgs[-1].filename)
size = imgs[-1].size
im = imgs[0]
print(len(imgs))
im.save(gif, save_all=True, append_images=imgs, loop=False)
print('wrote', gif)
@wyojustin
Copy link
Author

wyojustin commented Mar 6, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment