forked from gto76/python-cheatsheet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdate_plots.py
More file actions
executable file
·122 lines (100 loc) · 4.72 KB
/
update_plots.py
File metadata and controls
executable file
·122 lines (100 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#!/usr/bin/env python3
#
# Usage: ./update_plots.py
# Updates plots from the Plotly section so they show the latest data.
from pathlib import Path
from datetime import date, time, datetime, timedelta
import pandas as pd
from plotly.express import line
import plotly.graph_objects as go
import re
def main():
print('Updating covid deaths...')
update_covid_deaths()
print('Updating covid cases...')
update_confirmed_cases()
def update_covid_deaths():
def update_readme(date_treshold):
lines = read_file(Path('..') / 'README.md')
out = [re.sub("df.date < '\d{4}-\d{2}-\d{2}'", f"df.date < '{date_treshold}'", line)
for line in lines]
write_to_file(Path('..') / 'README.md', out)
covid = pd.read_csv('https://covid.ourworldindata.org/data/owid-covid-data.csv',
usecols=['iso_code', 'date', 'total_deaths', 'population'])
continents = pd.read_csv('https://datahub.io/JohnSnowLabs/country-and-continent-codes-' + \
'list/r/country-and-continent-codes-list-csv.csv',
usecols=['Three_Letter_Country_Code', 'Continent_Name'])
df = pd.merge(covid, continents, left_on='iso_code', right_on='Three_Letter_Country_Code')
df = df.groupby(['Continent_Name', 'date']).sum().reset_index()
df['Total Deaths per Million'] = df.total_deaths * 1e6 / df.population
date_treshold = str(date.today() - timedelta(days=2)) # '2020-11-25'
df = df[('2020-03-14' < df.date) & (df.date < date_treshold)]
df = df.rename({'date': 'Date', 'Continent_Name': 'Continent'}, axis='columns')
f = line(df, x='Date', y='Total Deaths per Million', color='Continent')
f.update_layout(margin=dict(t=24, b=0), paper_bgcolor='rgba(0, 0, 0, 0)')
update_file('covid_deaths.js', f)
update_readme(date_treshold)
write_to_png_file('covid_deaths.png', f, width=960, height=340)
def update_confirmed_cases():
def main():
df = wrangle_data(*scrape_data())
f = get_figure(df)
update_file('covid_cases.js', f)
write_to_png_file('covid_cases.png', f, width=960, height=315)
def scrape_data():
def scrape_yahoo(id_):
BASE_URL = 'https://query1.finance.yahoo.com/v7/finance/download/'
now = int(datetime.now().timestamp())
url = f'{BASE_URL}{id_}?period1=1579651200&period2={now}&interval=1d&' + \
'events=history'
return pd.read_csv(url, usecols=['Date', 'Close']).set_index('Date').Close
covid = pd.read_csv('https://covid.ourworldindata.org/data/owid-covid-data.csv',
usecols=['location', 'date', 'total_cases'])
covid = covid[covid.location == 'World'].set_index('date').total_cases
dow, gold, bitcoin = [scrape_yahoo(id_) for id_ in ('^DJI', 'GC=F', 'BTC-USD')]
dow.name, gold.name, bitcoin.name = 'Dow Jones', 'Gold', 'Bitcoin'
return covid, dow, gold, bitcoin
def wrangle_data(covid, dow, gold, bitcoin):
df = pd.concat([dow, gold, bitcoin], axis=1)
df = df.sort_index().interpolate()
df = df.rolling(10, min_periods=1, center=True).mean()
df = df.loc['2020-02-23':].iloc[:-2]
df = (df / df.iloc[0]) * 100
return pd.concat([covid, df], axis=1, join='inner')
def get_figure(df):
def get_trace(col_name):
return go.Scatter(x=df.index, y=df[col_name], name=col_name, yaxis='y2')
traces = [get_trace(col_name) for col_name in df.columns[1:]]
traces.append(go.Scatter(x=df.index, y=df.total_cases, name='Total Cases', yaxis='y1'))
figure = go.Figure()
figure.add_traces(traces)
figure.update_layout(
yaxis1=dict(title='Total Cases', rangemode='tozero'),
yaxis2=dict(title='%', rangemode='tozero', overlaying='y', side='right'),
legend=dict(x=1.1),
margin=dict(t=24, b=0),
paper_bgcolor='rgba(0, 0, 0, 0)'
)
return figure
main()
def update_file(filename, figure):
lines = read_file(filename)
f_json = figure.to_json(pretty=True).replace('\n', '\n ')
out = lines[:6] + [f' {f_json}\n', ' )\n', '};\n']
write_to_file(filename, out)
###
## UTIL
#
def read_file(filename):
p = Path(__file__).resolve().parent / filename
with open(p, encoding='utf-8') as file:
return file.readlines()
def write_to_file(filename, lines):
p = Path(__file__).resolve().parent / filename
with open(p, 'w', encoding='utf-8') as file:
file.writelines(lines)
def write_to_png_file(filename, figure, width, height):
p = Path(__file__).resolve().parent / filename
figure.write_image(str(p), width=width, height=height)
if __name__ == '__main__':
main()