Skip to content

Instantly share code, notes, and snippets.

@briochemc
Forked from mbauman/covid19.jl
Last active April 2, 2020 06:37
Show Gist options
  • Save briochemc/60960829be3ebecdfb3135f8637f2788 to your computer and use it in GitHub Desktop.
Save briochemc/60960829be3ebecdfb3135f8637f2788 to your computer and use it in GitHub Desktop.
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)
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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)
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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)
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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)
@briochemc
Copy link
Author

briochemc commented Mar 18, 2020

First output "Will Australia be like current Italy in ~3 weeks?"

covid19.jl output

Second output: All death cases above 10

covid19_deaths.jl output

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