Skip to content

Instantly share code, notes, and snippets.

@markusfisch
Last active September 25, 2020 18:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markusfisch/ba0e972ce610fbd14f4d29af08354dfc to your computer and use it in GitHub Desktop.
Save markusfisch/ba0e972ce610fbd14f4d29af08354dfc to your computer and use it in GitHub Desktop.
Create a simple chart showing the development of the COVID-19 7 day incidence score in your city

7 day incidence development chart

A Python script that creates a simple chart showing the development of the COVID-19 7 day incidence in your city (or cities of interest).

Data is taken from lgl.bayern.de so it works only for cities in Bayern, Germany.

How to use

Run the script with the names of the cities you want to have charted:

$ ./chart.py 'Erlangen' 'Fürth Stadt' 'Nürnberg Stadt'

The script should run every day so you see you the 7 day incidence is developing over time.

The script generates chart.png that contains the chart.

#!/usr/bin/env python3
import json
import matplotlib.pyplot as plt
import re
import requests
import sys
from datetime import datetime, timedelta
from lxml import etree, html as lxmlhtml
from os import path
def extract_date(html):
pattern = b'<script>var publikationsDatum = "'
pos = html.find(pattern)
if pos < 0:
return None
pos += len(pattern)
date = html[pos:pos + 10].decode('utf-8')
return datetime.strptime(date, '%d.%m.%Y')
def file_name_for_date(date):
return date.strftime('%Y%m%d')
def fetch(cities):
html = requests.get(
'https://www.lgl.bayern.de/gesundheit/infektionsschutz/infektionskrankheiten_a_z/coronavirus/karte_coronavirus/'
).content
date = extract_date(html)
if date is None:
return None
file_name = file_name_for_date(date)
tree = lxmlhtml.fromstring(html)
stats = {}
for city in cities:
for td in tree.xpath(
'//table[@id="tableLandkreise"]/tr/td[text() = "%s"]' % (city, ),
):
tr = td.getparent()
name = tr.xpath('td[1]')[0].text_content()
total = tr.xpath('td[2]')[0].text_content()
change = tr.xpath('td[3]')[0].text_content()
if change == '-':
change = '0'
seven = tr.xpath('td[6]')[0].text_content()
stats[name] = {
'total': int(total.replace('.', '')),
'change': int(change.strip('()').replace(' ', '')),
'seven': float(seven.replace(',', '.')),
}
with open(file_name, 'w') as f:
json.dump(stats, f)
return date
def main(cities):
if not cities or len(cities) < 1:
cities = ['Fürth Stadt', 'Nürnberg Stadt']
date = fetch(cities)
if date is None:
return
days = []
changes = {}
for i in range(-6, 1):
d = date + timedelta(days=i)
file_name = file_name_for_date(d)
if path.isfile(file_name):
with open(file_name) as f:
stats = json.load(f)
days.append(d.strftime('%a %d'))
for city in cities:
if city not in changes:
changes[city] = []
changes[city].append(stats[city]['seven'])
for city in cities:
plt.plot(days, changes[city], marker='o', label=city)
plt.legend()
plt.title('Entwicklung 7 Tage Inzidenz pro 100.000 Einwohner')
plt.xlabel('Datum')
plt.ylabel('Inzidenz')
plt.savefig('chart.png')
if __name__ == '__main__':
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment