Published
Edited
Dec 29, 2020
Importers
6 stars
Andy's Walgreens COVID-19 Tracker TrackerBelgium Vaccination Tracker - Progress of the vaccination campaignVaccination against covid-19 in France500,000 COVID-19 DeathsCovid-19 vaccinations: BubblesTime Spiral with a COVID DemoCOVID MasksGrid Cartogram component with live COVID demos (plus a MapEditor)The US COVID SyringeCOVID-19 DKCOVID-19 World Community Mobility Report by GoogleCOVID 19Chicago COVID ZIP SparklinesThe COVID Syringeభారతదేశంలో కోవిడ్-19SVG DataGrid with many features and a live COVID Dashboard demoThe spread of Covid-19 in New MexicoHeatmap of COVID-19 Confirmed Cases by Age over Time in JapanThe CoViD-19 ReportCovid19 WorldwideMassachusetts Coronavirus Cases by TownChoropleth map about Covid19 in France
Well ordered coronavirus heatmaps for US and the World
COVID-19 Racial/Ethnic Mortality AnalysisProPublica's COVID Arrow MapClustering students to slow virus spread inside schoolsCOVID-19 in the USAWho Is Wearing Masks in the U.S.Covid-19 Viz RoundupCoronavirus StatsThe Covid-19 Crisis' Impact on the Number of US Flight PassengersCOVID-19 Daily New CasesCOVID-19 CasesCOVID–19 Bubble Chart with D3 RenderCoronavirus Deaths by Race / EthnicityHow many SARS-CoV-2 tests are we running in the U.S.?COVID-19 Onset vs. ConfirmationPeaks in confirmed daily deaths due to COVID-19 so farCOVID-19 in the U.S.Recreating John Burn-Murdoch’s Coronavirus trackerTracking COVID-19 Cases in VietnamCOVID-19 in NYC by Zip Code & IncomeVisualizing the Network Meta-Analysis of Covid-19 Studiesxkcd COVID-19 spread sketchCOVID-19's deaths in EuropeCovid-19 (corona virus) deaths per 1,000,000 peopleCOVID-19 Bubble map or spike map? (Twitter debate)A Timeline of Shelter-in-PlaceWhere’s that $2 trillion going?Estimating SARS-COV-2 infectionsCODAVIM - CountySARS-CoV-2 Epi CurveCOVID-19 Curves (U.S.)COVID-19 Cases by CountyCOVID-19 world growth rateA graphical experiment of exponential spreadCOVID-19 by US countyCOVID-19 Confirmed vs. New cases"Live" Logistic Coronavirus Death CounterInfografiche: COVID-19 in ItaliaCoronavirus (COVID-19) GlobeBar Chart Race, COVID-19 outbreak Worldwide to 24th March 2020US Coronavirus testing by statesUnited States Coronavirus Daily Cases Map (COVID-19)COVID-19 Numbers by State, Side by SideRecreating NYT U.S. Cases MapCOVID-19 in Washington stateCOVID-19 outbreak in maps and chartsCOVID-19 Spreading trendsRestaurants during COVID-19 social distancingCOVID-19 Countries Trajectories in 3DStates that aren't reporting aspects of their COVID-19 testing processNextstrain Prototyping - Issue 817Reviewing COVID-19 SARS-CoV-2 preprints from medRxiv and bioRxivCoronavirus worldwide evolutionCovid-19 New Cases PunchcardCovid-19 cases per district in Germany.COVID-19 Cases, Deaths, and Recoveries (Select Country)Quarantine NowEmissions in WuhanCOVID-19(nCOV-2019) Outbreak in S.KoreaMovement of population between provinces in 2019-nCoVComparing COVID-19 GrowthCovid-19 derived chartCoronavirus Trends (COVID-19)Netherlands Coronavirus Daily Cases Map (COVID-19)Map and timeline of Corona outbreakSARS-CoV-2 Phylogenetic TreeCoronavirus data (covid-19)Visualizing the Logic of Exponential Viral SpreadItaly Coronavirus Daily Cases Map (COVID-19)COVID-19 Fatality Rate
Insert cell
Insert cell
viewof metric = radio({title: "color", options: [{value: "change", "label": "rate of change"}, "percapita"], value:"percapita"})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
state_field = {
if (transform == "change") {
return `change_${state_metric}`
}
if (transform == "number") {
return `rolling_${state_metric}`
}
if (transform == "Per capita") {
return `${state_metric}_per_capita`
}
}
Insert cell
Insert cell
times = aq
.fromCSV(await d3.text('https://raw.githubusercontent.com/nytimes/covid-19-data/master/us-counties.csv'))
.derive({fips: d => d.fips ? d.fips : d.county=="New York City" ? "36061" : d.county=="Kansas City" ? "29380" : d.fips})
Insert cell
times2 = times
.groupby(["state", "fips"])
.orderby("date")
.derive({"new": d => d.cases - op.lag(d.cases, 1, 0)})
Insert cell
function fill_zeros(frame, cola, colb) {
// must have a column called 'count'.
const values = frame.select([cola]).dedupe().join_full(frame.select([colb]).dedupe(), [[], []])
const names = frame.columnNames().filter(d => d != cola && d!==colb)
return frame
.join_full(values, [[cola, colb], [cola, colb]], [names, [cola, colb]])
.derive({count: d => d.count ? d.count : 0})
}
Insert cell
times2.columnNames()
Insert cell
covid_tracking = d3.csv("https://api.covidtracking.com/v1/states/daily.csv").then(d => d.map(e => {
e.date = d3.timeParse("%Y%m%d")(e.date);
for (let field of ["positiveIncrease", "deathIncrease", "hospitalizedCurrently"]) {
e[field] = +e[field]
}
return e}))
Insert cell
viewof covid_tracking_states =
{
const rawest = aq.from(covid_tracking)
.select(["date", "state", "positiveIncrease", "deathIncrease", "hospitalizedCurrently"])
const dates = rawest.select("date").dedupe().reify()
const unique_states = rawest.select("state").dedupe().reify()
const all_combos = dates.join_full(unique_states, [[], []])
let filled_a_bit = rawest
.join_full(all_combos, [['date', 'state'], ['date', 'state']], [["positiveIncrease", "deathIncrease", "hospitalizedCurrently"], ['date', 'state']])
// fill NA.
.derive({
"positive": d => d.positiveIncrease ? d.positiveIncrease : 0,
"rolling_hospitalized": d => d.hospitalizedCurrently ? d.hospitalizedCurrently : 0,
"deaths": d => d.deathIncrease ? d.deathIncrease : 0}
)
.join(states, [["state"], ["state_abbr"]], [["positive", "date", "state", "rolling_hospitalized", "deaths"], ["pop"]])
.groupby("state")
.orderby("date")
.params({lag: TIME_HORIZON})
.derive({"rolling_positive": aq.rolling((d, $) => op.sum(d.positive), [-TIME_HORIZON, 0]),
"rolling_deaths": aq.rolling((d, $) => op.sum(d.deaths), [-TIME_HORIZON, 0])
})
.derive(
{"change_positive": (d, $) => d.rolling_positive / op.lag(d.rolling_positive, $.lag),
"change_deaths": (d, $) => d.rolling_deaths / op.lag(d.rolling_deaths, $.lag),
"change_hospitalized": (d, $) => d.rolling_hospitalized / op.lag(d.rolling_hospitalized, $.lag)
})
.derive(
{"positive_per_capita": (d, $) => d.rolling_positive / d.pop,
"deaths_per_capita": (d, $) => d.rolling_deaths / d.pop,
"hospitalized_per_capita": (d, $) => d.rolling_hospitalized / d.pop
}).select(["state", "date",
"positive_per_capita", "deaths_per_capita", "hospitalized_per_capita",
"change_positive", "change_deaths", "change_hospitalized",
"rolling_positive", "rolling_deaths", "rolling_hospitalized"])


return filled_a_bit.view()
}
Insert cell
re_rolled = {
// return all_combos
const dates = times2.select("date").dedupe().reify()
const states = times2.select("state").dedupe().reify()
const all_combos = dates.join_full(states, [[], []])
return times2.groupby(["date", "state"])
.rollup({"new": d => op.sum(d.new)})
.join_full(all_combos, [['date', 'state'], ['date', 'state']], [['new'], ['date', 'state']])
// fill NA.
.derive({"new": d => d.new ? d.new : 0})
}
Insert cell
Insert cell
with_pops = re_rolled
.groupby("state")
.orderby("date")
.derive({"new": aq.rolling(d => op.sum(d.new), [-7, 0])})
.derive({"change": d => d.new / op.lag(d.new, 7)})
.join(states, [["state"], ["state_name"]], [["new", "date", "state", "change"], ["pop"]])
.derive({percapita: d => d.new / d.pop})

Insert cell
Insert cell
Insert cell
msas = aq.table({"fips": Object.keys(metros), "msa": Object.values(metros)})
Insert cell
best_sorting_order = [
["Pacific Ocean", "Guam AKA GU", "Hawaii AKA HI", "Alaska AKA AK"],
["Lower 48",
["West",
["West Coast",
["Pacific Northwest", "WA", "OR"],
"CA"
],
["Southwest", "AZ", "NM", "NV"],
"CO",
"WY",
"UT",
"ID",
"MT"
],
["Midwest",
["Dakotas", "ND","SD"],
"NE","KS","IA",
"MN","WI", "MI", "OH","IN","IL"
],
["South", "MO",
"OK","TX","LA","AR",
"KY","TN",
"MS","AL","GA","FL",
"SC","NC","WV","VA"],
["Northeast",
["Mid-Atlantic",
"DC","MD","DE","PA","NJ","NY"
],
["New England",
["Southern New England",
"CT","RI","MA"],
["Northern New England", "NH","VT","ME"]
]
],
["Carribean", "Puerto Rico AKA PR", "US Virgin Islands"]
]
].flat(10).map(k => [k, state_info.get(k) ? state_info.get(k).state_name : undefined]).flat().filter(d => d!=undefined)
Insert cell
function cleanup(frame, populations, groups = ["state"], date = "date") {
return frame
// .derive({"date": d => op.week(d[date])})
// .derive({"date": d => new Date(2020, 0, 7 * d.date)})
.groupby([...groups, date])
.rollup({count: d => op.sum(d.new)})
.join_left(populations, [groups, groups], [[...groups, "date", "count"], ["pop"]])
.groupby(groups)
.derive({change: d => d.count/op.lag(d.count, 1, 1), "percapita": d => d.count/d.pop})
}
Insert cell
state_pops = {
const pops = await d3.json("https://raw.githubusercontent.com/CivilServiceUSA/us-states/master/data/states.json").then(d => d3.rollup(d, data => data[0].population, k => k.code))
pops.set("PR", 2860853)
pops.set("DC", 684498)
return pops
}
Insert cell
Insert cell
viewof states = aq.from(state_info.values()).dedupe().view()
Insert cell
Insert cell
Insert cell
root_ordering = countries.array
Insert cell
aliases = countries.alias_map()
Insert cell
import { countries } from '12cd50fc650b98a9';
Insert cell
viewof country_cases = {
const unfull = aq
.from(hopkins)
.groupby(["Country/Region", "Province/State"]).orderby("date")
.derive({new: d => d.positive - op.lag(d.positive, 1, 0)})
.groupby(["Country/Region", "date"])
.rollup({count: d => op.sum(d.new)})
.filter(d => d.count > 0)
const filled = fill_zeros(unfull, "Country/Region", "date")
populations.forEach(d => d.population_total = +d.population_total)

return filled.join_left(aq.from(populations), [["Country/Region"], ["name"]],
[filled.columnNames(), ['population_total']])
.derive({pop: d => d.population_total})
.groupby("Country/Region")
.derive({share: d => d.count/op.sum(d.count)})
.orderby("date")
.derive({"new": aq.rolling((d, $) => op.sum(d.count), [-TIME_HORIZON, 0])})
.params({TIME_HORIZON: TIME_HORIZON})
.derive({"change": (d, $) => d.new / op.lag(d.new, $.TIME_HORIZON)})
.derive({percapita: d => d.new / d.pop})
.filter(d => d["Country/Region"] !== undefined)
.view(10)
}
Insert cell
populations = populations_raw.map(d => {
// Add some additional possible populations.
const output = []
for (let alias of aliases.get(d.name)) {
output.push({"name": alias, "population_total": d.population_total})
}
return output
}).flat(1)
Insert cell
Insert cell
embed = require("vega-embed@6")
Insert cell
metros = d3.json("https://gist.githubusercontent.com/bmschmidt/62ed8da02750cbf0b75278cfe06f7bb7/raw/37cc7dfe54b71c041fbc2d3d9cd214443d206c3c/msa-csa.json")
Insert cell
d3 = require("d3@v6")
Insert cell
import { aq, op } from '@uwdata/arquero'
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more