-
-
Save briochemc/60960829be3ebecdfb3135f8637f2788 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using HTTP, CSV, Plots, DataFrames, Dates | |
# Download the data | |
df = CSV.read(IOBuffer(String(HTTP.get("https://covid.ourworldindata.org/data/total_cases.csv").body)), normalizenames=true) | |
# Plotting function | |
function doit(df, countries, alignment) | |
cp = get_color_palette(:auto, plot_color(:white), length(countries)) | |
plot(legend=false) | |
for (i,country) in enumerate(countries) | |
c = df[:, country] | |
d = map(x -> x.value, df.date .- df.date[findfirst(coalesce.(c,0) .>= alignment)]) | |
plot!(d, c, color=i, yaxis=:log, m=:circle, ms=2, msw=false, lw=2, label="") | |
plot!([d[end]], [c[end]], color=cp[i], yaxis=:log, m=:circle, ms=3, label="") | |
# annotate country next to end point instead of legend | |
annotate!(d[end]+1, c[end], text("$(replace(string(country), "_"=>" "))", 8, :left, :bold, color=cp[i])) | |
end | |
xlabel!("Days since $(alignment)th case") | |
ylabel!("Cumulative number of cases") | |
# pretty lims | |
xlims!(-1, last(xlims())+4) | |
ylims!(alignment*.8, last(ylims())) | |
yticks=vec([1,2,5] * 10 .^ (1:4)') | |
# pretty ticks | |
yticks=yticks[alignment .≤ yticks .≤ maximum(df[end,countries])] | |
plot!(yticks=(yticks, string.(yticks)), xticks=0:7:last(xlims())+4) | |
end | |
function addtrend(df, dailygrowth, alignment) | |
d = 0:last(xlims()) | |
c = alignment * (1 + dailygrowth) .^ (d) | |
plot!(d, c, ls=:dot, color=:gray, lw=2, label="+$(100dailygrowth)% daily") | |
plot!(legend=:bottomright) | |
end | |
# Do it! (plotting the data) | |
doit(df, [:China, :Italy, :France, :Spain, :Australia, :United_States, :United_Kingdom, :Singapore, :South_Korea], 100) | |
addtrend(df, 0.25, 100) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using HTTP, CSV, Plots, DataFrames | |
# Download the data | |
df = CSV.read(IOBuffer(String(HTTP.get("https://covid.ourworldindata.org/data/total_deaths.csv").body)), normalizenames=true) | |
# Plotting function | |
function doit(df, countries, alignment) | |
countries = countries[findall(map(x -> ismissing(x) ? false : x > alignment, Vector(df[end, countries])))] | |
cp = get_color_palette(:auto, plot_color(:white), length(countries)) | |
plot(legend=false) | |
for (i, country) in enumerate(countries) | |
c = df[:, country] | |
(c[end] isa Missing || c[end] < alignment) && continue | |
d = map(x -> x.value, df.date .- df.date[findfirst(coalesce.(c,0) .>= alignment)]) | |
plot!(d, c, color=cp[i], yaxis=:log, m=:circle, ms=2, msw=false, lw=2, label="") | |
plot!([d[end]], [c[end]], color=cp[i], yaxis=:log, m=:circle, ms=3, label="") | |
# annotate country next to end point instead of legend | |
annotate!(d[end]+1, c[end], text("$(replace(string(country), "_"=>" "))", 8, :left, :bold, color=cp[i])) | |
end | |
xlabel!("Days since $(alignment)th death") | |
ylabel!("Cumulative number of deaths") | |
# pretty lims | |
xlims!(-1, last(xlims())+4) | |
ylims!(alignment*.8, last(ylims())) | |
# pretty ticks | |
yticks=vec([1,2,5] * 10 .^ (0:4)') | |
yticks=yticks[alignment .≤ yticks .≤ maximum(df[end,countries])] | |
plot!(yticks=(yticks, string.(yticks)), xticks=0:7:last(xlims())+4) | |
end | |
function addtrend(df, dailygrowth, alignment) | |
d = 0:last(xlims()) | |
c = alignment * (1 + dailygrowth) .^ (d) | |
plot!(d, c, ls=:dot, color=:gray, lw=2, label="+$(100dailygrowth)% daily") | |
plot!(legend=:bottomright) | |
end | |
# Do it! (plotting the data) | |
doit(df, names(df)[3:end], 10) | |
addtrend(df, 0.25, 10) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using HTTP, CSV, Plots, DataFrames, Dates | |
file_url = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv" | |
# Download the data | |
df = CSV.read(IOBuffer(String(HTTP.get(file_url).body)), normalizenames=true, header=2, transpose=true, datarow=5) | |
const allcountries = unique(replace.(string.(names(df)), r"_\d*$"=>""))[2:end] | |
# Plotting function | |
function doit(df, countries, lockdowndict=Dict(); Δdays=1) | |
cp = get_color_palette(:auto, plot_color(:white), length(countries)) | |
plot(xaxis=:log, yaxis=:log) | |
for country in allcountries | |
country == "Cruise_Ship" && continue | |
country == "Diamond_Princess" && continue | |
i = findfirst(Symbol(country) .== countries) | |
if i isa Nothing | |
color, m, ms, α, mα, lw, fs = RGBA{Float64}(0,0,0,0.1), 0, 0, 0.1, 0, 1, 4 | |
elseif country == "Australia" | |
color, m, ms, α, mα, lw, fs = cp[i], :star, 4, 1, 0, 4, 12 | |
else | |
color, m, ms, α, mα, lw, fs = cp[i], :circle, 2, 0.5, 0, 2, 8 | |
end | |
cases = Float64.(sum(eachcol(select(df, occursin.(string(country), string.(names(df))))))) | |
Δcases = cases[1+Δdays:end] - cases[1:end-Δdays] | |
cases = cases[1+Δdays:end] | |
ikeep = findall((cases .> 0) .& (Δcases .> 0)) | |
cases = cases[ikeep] | |
Δcases = Δcases[ikeep] | |
(any(Δcases .≤ 0) || length(ikeep) == 0) && continue | |
plot!(cases, Δcases, color=color, m=m, ms=ms, msw=0, lw=lw, α=α, mα=mα, label="") | |
plot!([cases[end]], [Δcases[end]], color=color, m=m, α=1, ms=ms+1, msw=0, label="") | |
# annotate country next to end point instead of legend | |
cases[end] > 30 && Δcases[end] > 10 && annotate!(cases[end] * 1.1, Δcases[end], text("$(replace(string(country), "_"=>" "))", fs, :left, :bold, color=color)) | |
end | |
# axis labels | |
xlabel!("Total confirmed cases") | |
ylabel!("Δcases over $Δdays days") | |
# pretty lims | |
ticks=vec([1,3] * 10 .^ (0:5)') | |
plot!(xlims=(30,last(xlims()))) | |
plot!(ylims=(10,last(ylims()))) | |
xticks = ticks[first(xlims()) .≤ ticks .≤ last(xlims())] | |
yticks = ticks[first(ylims()) .≤ ticks .≤ last(ylims())] | |
# pretty ticks | |
plot!(xticks=(xticks, addprefix.(string.(xticks))), yticks=(yticks, addprefix.(string.(yticks)))) | |
Δx, cstart = collect(xlims()), 300 | |
growth(Δx, cstart, 1, Δdays, :solid) | |
growth(Δx, cstart, 3, Δdays, :dash, "") | |
growth(Δx, cstart, 7, Δdays, :dashdot, "") | |
growth(Δx, cstart, 21, Δdays, :dot, "") | |
plot!(legend=:topleft, legendtitle="Doubling time") | |
end | |
Δc_vs_c(c, τ, Δdays) = (1 - 0.5^(Δdays/τ)) .* c | |
function growth(Δx, cstart, τ, Δdays, ls, str=" in $Δdays days") | |
α = log(2) / τ | |
c = cstart * exp.(α*Δdays*[0,1]) | |
plot!(Δx, Δc_vs_c(Δx, τ, Δdays), ls=ls, color=:gray, lw=1, label="$τ days") | |
plot!(c, Δc_vs_c(c, τ, Δdays), m=[:circle, :dtriangle], ms=2, ls=:solid, color=:black, lw=1, label="") | |
str = "×$(round(c[end]/c[1], digits=1))$str" | |
if length(str) > 10 | |
annotate!(c[end] * 0.8, Δc_vs_c(c, τ, Δdays)[end], text(str, 8, :right, color=:black)) | |
else | |
annotate!(c[end] * 1.1, Δc_vs_c(c, τ, Δdays)[end], text(str, 8, :left, color=:black)) | |
end | |
end | |
function addprefix(s) | |
s = replace(s, r"(.*)000000000$"=>s"\1G") | |
s = replace(s, r"(.*)000000$"=>s"\1M") | |
s = replace(s, r"(.*)000$"=>s"\1k") | |
return s | |
end | |
function addtrend(xlims, trend, Δdays) | |
plot!(collect(xlims), trend * Δdays * collect(xlims), ls=:dot, color=:gray, lw=2, label="+$(100trend)%", legend=:topleft) | |
end | |
function adddoublingtime(Δx, τ, Δdays) | |
plot!(Δx, Δx * 1 ./ τ' * Δdays, ls=:dot, color=:gray, lw=2, label=string.(τ, " days"), legend=:topleft) | |
end | |
lockdowndict = Dict( | |
:Australia => nothing, | |
:Italy => Date("9 March 2020", dateformat"d U Y"), | |
:France => Date("16 March 2020", dateformat"d U Y"), | |
:China => Date("23 January 2020", dateformat"d U Y"), | |
) | |
# Do it! (plotting the data) | |
#countries = [:China, :Canada, :Turkey, :India, :Iraq, :Bahrain, :Iran, :Germany, :Switzerland, :Netherlands, :Belgium, :Italy, :France, :Spain, :Australia, :US, :United_Kingdom, :Singapore, :Korea_South, :Japan, :Norway, :Finland, :Sweden] | |
countries = [:China, :Canada, :Italy, :France, :Spain, :Australia, :US, :United_Kingdom, :Singapore, :Korea_South, :Japan] | |
doit(df, countries, lockdowndict; Δdays=3) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using HTTP, CSV, Plots, DataFrames, Dates | |
file_url = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv" | |
# Download the data | |
df = CSV.read(IOBuffer(String(HTTP.get(file_url).body)), normalizenames=true, header=2, transpose=true, datarow=5) | |
const allcountries = unique(replace.(string.(names(df)), r"_\d*$"=>""))[2:end] | |
# Plotting function | |
function doit(df, countries, alignment, lockdowndict=Dict()) | |
cp = get_color_palette(:auto, plot_color(:white), length(countries)) | |
plot(legend=false, yaxis=:log) | |
dates = Date.(df.Country_Region, dateformat"mm/dd/yy") .+ Year(2000) | |
days = [d.value for d in (dates .- dates[1])] | |
n = length(days) | |
for country in allcountries | |
country == "Cruise_Ship" && continue | |
i = findfirst(Symbol(country) .== countries) | |
if i isa Nothing | |
color, m, ms, α, ma, lw, fs = RGBA{Float64}(0,0,0,0.1), 0, 0, 0.1, 0, 1, 4 | |
elseif country == "Australia" | |
color, m, ms, α, ma, lw, fs = cp[i], :star, 4, 1, 0, 4, 12 | |
else | |
color, m, ms, α, ma, lw, fs = cp[i], :circle, 2, 0.5, 0, 2, 8 | |
end | |
cases = Float64.(sum(eachcol(select(df, occursin.(string(country), string.(names(df))))))) | |
# alignment by interpolating | |
if cases[1] > alignment | |
baseline = -cases[1] / (cases[2] - cases[1]) | |
elseif cases[end] < alignment | |
continue | |
else | |
ialign = findlast(cases .< alignment) | |
baseline = ialign + (alignment - cases[ialign]) / (cases[ialign+1] - cases[ialign]) - 1 | |
end | |
# don't plot 0 values | |
cases[cases .== 0] .= NaN | |
plot!(days .- baseline, cases, color=color, m=m, ms=ms, msw=0, lw=lw, alpha=α, ma=ma, label="") | |
plot!([days[end] - baseline], [cases[end]], color=color, m=m, alpha=1, ms=ms+1, msw=0, label="") | |
# annotate country next to end point instead of legend | |
annotate!(days[end] - baseline + 0.5, cases[end], text("$(replace(string(country), "_"=>" "))", fs, :left, :bold, color=color)) | |
end | |
# axis labels | |
xlabel!("Days since $(alignment)th case") | |
ylabel!("Cumulative number of cases") | |
# pretty lims | |
xlims!(0, last(xlims())+4) | |
ylims!(alignment, last(ylims())) | |
yticks=vec([1,2,5] * 10 .^ (1:4)') | |
# pretty ticks | |
yticks=yticks[first(ylims()) .≤ yticks .≤ last(ylims())] | |
plot!(yticks=(yticks, string.(yticks)), xticks=0:7:last(xlims())+4) | |
end | |
lockdowndict = Dict( | |
:Australia => nothing, | |
:Italy => Date("9 March 2020", dateformat"d U Y"), | |
:France => Date("16 March 2020", dateformat"d U Y"), | |
:China => Date("23 January 2020", dateformat"d U Y"), | |
) | |
function addtrend(dailygrowth, alignment) | |
d = 0:last(xlims()) | |
c = alignment * (1 + dailygrowth) .^ (d) | |
plot!(d, c, ls=:dot, color=:gray, lw=2, label="+$(100dailygrowth)% daily") | |
plot!(legend=:bottomright) | |
end | |
# Do it! (plotting the data) | |
countries = [:China, :Turkey, :India, :Iraq, :Bahrain, :Iran, :Germany, :Switzerland, :Netherlands, :Belgium, :Italy, :France, :Spain, :Australia, :US, :United_Kingdom, :Singapore, :Korea_South, :Japan, :Norway, :Finland, :Sweden] | |
doit(df, countries, 100, lockdowndict) | |
addtrend(0.25, 100) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
First output "Will Australia be like current Italy in ~3 weeks?"
Second output: All death cases above 10