- 您可以从OWID 获取包括人口数据在内的 COVID 数据
- 看来这是您从制造商那里获取数据的地方
- 我可以将数据与整体 COVID 数据合并,以便您记录的所有属性都可用
- 已使用 plotly,因此它是交互式隐藏/显示痕迹
- 注意,没有多少国家/地区按制造商发布数据
import requests, io
import pandas as pd
# get data by manufactuerer
dfm = pd.read_csv(io.StringIO(
requests.get("https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/vaccinations-by-manufacturer.csv").text))
# get all COVID data
dfall = pd.read_csv(io.StringIO(
requests.get("https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/owid-covid-data.csv").text))
# join two datasets together and make manufactuerer data columns. NB not all countries publish this data...
dfv = (
dfall.set_index(["location", "date"])
.join(
dfm.set_index(["location", "date", "vaccine"])
.unstack("vaccine")
.droplevel(0, 1),
how="inner",
)
.reset_index()
)
# filter to latest data only
dfplot = (
dfv.sort_values(["iso_code", "date"])
.groupby("iso_code", as_index=False)
.last()
.sort_values("people_fully_vaccinated_per_hundred", ascending=False)
)
import plotly.express as px
import plotly.graph_objects as go
# use plotly so it's interactive. rebase vaccines given by population
fig = px.bar(
dfplot.assign(
**{c: dfplot[c] / dfplot["population"] for c in dfm["vaccine"].unique()}
),
x="location",
y=dfm["vaccine"].unique(),
)
# add a line of people fully vaccinated
fig.add_trace(
go.Scatter(
x=dfplot["location"],
y=dfplot["people_fully_vaccinated_per_hundred"] / 100,
name="Fully vaccinated",
mode="lines",
line={"color": "purple", "width": 4},
)
)
更新
- 原始要求规定接种疫苗的人数百分比是必需的。这已根据 cmets 删除
- 需求确实被重述为交互式仪表板,因此使用了 dash
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
import dash_table
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output, State
import requests, io
import pandas as pd
import plotly.express as px
# get data by manufactuerer
dfm = pd.read_csv(io.StringIO(
requests.get("https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/vaccinations/vaccinations-by-manufacturer.csv").text))
def buildTab(col="location"):
dfc = pd.DataFrame({col: dfm[col].unique()})
return dash_table.DataTable(
id=col,
columns=[{"name": c, "id": c} for c in dfc.columns],
data=dfc.to_dict("records"),
row_selectable="multi",
style_header={"fontWeight": "bold"},
style_as_list_view=True,
css=[{"selector": ".dash-spreadsheet tr", "rule": "height: 5px;"}],
)
# Build App
app = JupyterDash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div(
[
dbc.Row(
[
dbc.Col(
buildTab(col="location"),
width=3,
style={"height": "20vh", "overflow-y": "auto"},
),
dbc.Col(
buildTab(col="vaccine"),
width=3,
style={"height": "20vh", "overflow-y": "auto"},
),
],
),
html.Div(id="graphs"),
],
style={
"font-family": "Arial",
"font-size": "0.9em",
},
)
@app.callback(
Output(component_id="graphs", component_property="children"),
Input("location", "selected_rows"),
Input("vaccine", "selected_rows"),
State("location", "data"),
State("vaccine", "data"),
)
def updateGraphs(selected_location, selected_vaccine, location, vaccine):
global dfm
if selected_location and selected_vaccine:
d = dfm.merge(
pd.DataFrame(location).iloc[selected_location], on="location", how="inner"
).merge(pd.DataFrame(vaccine).iloc[selected_vaccine], on="vaccine", how="inner")
return dcc.Graph(
figure=px.bar(
d.sort_values(["location", "vaccine", "date"])
.groupby(["location", "vaccine"], as_index=False)
.last(),
x="location",
y="total_vaccinations",
color="vaccine",
)
)
else:
return None
# Run app and display result inline in the notebook
app.run_server(mode="inline")