Covid_Tracker / app.py
your_username
Deploy COVID tracker dashboard
23f4e1a
Raw
History Blame Contribute Delete
7.38 kB
import streamlit as st
import pandas as pd
import plotly.express as px
# ------------------------------------------------------------------
# Configuration de la page
# ------------------------------------------------------------------
st.set_page_config(
page_title="Mon Tracker COVID perso",
page_icon="📊",
layout="wide",
)
# Image locale en haut du dashboard
#st.image("Covid.png", use_column_width=True)
# Titre et intro
st.title("Covid Tracker 🦠")
st.markdown(
"Dashboard de suivi des vagues de COVID-19 à travers le monde, "
"basé sur les données de l'European Centre for Disease Prevention and Control (ECDC)."
)
# ------------------------------------------------------------------
# Chargement des données (mis en cache pour la rapidité)
# ------------------------------------------------------------------
@st.cache_data
def load_data():
df = pd.read_csv("covid_data.csv")
df["dateRep"] = pd.to_datetime(df["dateRep"], format="%d/%m/%Y")
return df
df = load_data()
# ------------------------------------------------------------------
# Barre latérale : tous les filtres ensemble
# ------------------------------------------------------------------
st.sidebar.header("Filtres")
# Filtre par continent
continents = sorted(df["continentExp"].unique())
selected_continent = st.sidebar.selectbox("Continent", continents)
# Filtre par pays
countries = sorted(df[df["continentExp"] == selected_continent]["countriesAndTerritories"].unique())
selected_countries = st.sidebar.multiselect(
"Pays à afficher",
options=countries,
default=countries[:4] if len(countries) >= 4 else countries,
)
# Filtre par plage de dates
min_date = df["dateRep"].min().date()
max_date = df["dateRep"].max().date()
date_range = st.sidebar.date_input(
"Plage de dates",
value=(min_date, max_date),
min_value=min_date,
max_value=max_date,
)
# Slider pour le top N pays
top_n = st.sidebar.slider("Afficher le top N pays", min_value=3, max_value=20, value=10)
# Échelle logarithmique
log_scale = st.sidebar.checkbox("Échelle logarithmique")
# ------------------------------------------------------------------
# Filtrage du dataframe selon les choix utilisateur
# ------------------------------------------------------------------
filtered = df[df["continentExp"] == selected_continent]
filtered = filtered[filtered["countriesAndTerritories"].isin(selected_countries)]
if len(date_range) == 2:
start, end = date_range
filtered = filtered[
(filtered["dateRep"] >= pd.to_datetime(start))
& (filtered["dateRep"] <= pd.to_datetime(end))
]
# ------------------------------------------------------------------
# Onglets pour organiser le dashboard
# ------------------------------------------------------------------
tab1, tab2, tab3 = st.tabs(["Vue d'ensemble", "Par pays", "Comparaisons"])
# ----- ONGLET 1 : Vue d'ensemble -----
with tab1:
st.subheader("Indicateurs globaux")
col1, col2, col3 = st.columns(3)
total_cases = int(filtered["cases"].sum())
total_deaths = int(filtered["deaths"].sum())
mortality_rate = (total_deaths / total_cases * 100) if total_cases > 0 else 0
col1.metric("Cas totaux", f"{total_cases:,}".replace(",", " "))
col2.metric("Décès totaux", f"{total_deaths:,}".replace(",", " "))
col3.metric("Taux de mortalité", f"{mortality_rate:.2f} %")
# Courbe des cas dans le temps
st.subheader("Évolution des cas dans le temps")
fig_cases = px.line(
filtered,
x="dateRep",
y="cases",
color="countriesAndTerritories",
labels={"dateRep": "Date", "cases": "Cas quotidiens",
"countriesAndTerritories": "Pays"},
log_y=log_scale,
)
st.plotly_chart(fig_cases, use_container_width=True)
# Courbe des décès dans le temps
st.subheader("Évolution des décès dans le temps")
fig_deaths = px.line(
filtered,
x="dateRep",
y="deaths",
color="countriesAndTerritories",
labels={"dateRep": "Date", "deaths": "Décès quotidiens",
"countriesAndTerritories": "Pays"},
log_y=log_scale,
)
st.plotly_chart(fig_deaths, use_container_width=True)
# ----- ONGLET 2 : Par pays -----
with tab2:
st.subheader("Récapitulatif par pays")
summary = (
filtered.groupby("countriesAndTerritories")
.agg(
cas_totaux=("cases", "sum"),
deces_totaux=("deaths", "sum"),
cas_moyens_par_jour=("cases", "mean"),
)
.round(0)
.sort_values("cas_totaux", ascending=False)
)
st.dataframe(summary, use_container_width=True)
# Bouton pour télécharger le résumé en CSV
csv = summary.to_csv().encode("utf-8")
st.download_button(
label="📥 Télécharger le résumé en CSV",
data=csv,
file_name="covid_summary.csv",
mime="text/csv",
)
# Données brutes (déplié sur demande)
with st.expander("Voir les données brutes filtrées"):
st.dataframe(filtered)
# ----- ONGLET 3 : Comparaisons -----
with tab3:
# Carte mondiale colorée par cas totaux
st.subheader("Carte mondiale des cas")
map_data = (
filtered.groupby(["countryterritoryCode", "countriesAndTerritories"])
.agg(total_cases=("cases", "sum"))
.reset_index()
)
fig_map = px.choropleth(
map_data,
locations="countryterritoryCode",
color="total_cases",
hover_name="countriesAndTerritories",
color_continuous_scale="Reds",
)
st.plotly_chart(fig_map, use_container_width=True)
# Cas cumulés par pays en aires empilées
st.subheader("Cas cumulés par pays")
fig_area = px.area(
filtered,
x="dateRep",
y="cases",
color="countriesAndTerritories",
labels={"dateRep": "Date", "cases": "Cas"},
)
st.plotly_chart(fig_area, use_container_width=True)
# Cas par jour de la semaine
st.subheader("Cas par jour de la semaine")
filtered_copy = filtered.copy()
filtered_copy["weekday"] = filtered_copy["dateRep"].dt.day_name()
weekday_avg = filtered_copy.groupby("weekday")["cases"].mean().reindex(
["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
)
st.bar_chart(weekday_avg)
# Moyenne mobile 7 jours
st.subheader("Tendance lissée (moyenne mobile 7 jours)")
filtered_sorted = filtered.sort_values(["countriesAndTerritories", "dateRep"])
filtered_sorted["cases_7day_avg"] = (
filtered_sorted.groupby("countriesAndTerritories")["cases"]
.transform(lambda x: x.rolling(7, min_periods=1).mean())
)
fig_smooth = px.line(
filtered_sorted,
x="dateRep",
y="cases_7day_avg",
color="countriesAndTerritories",
)
st.plotly_chart(fig_smooth, use_container_width=True)
# Taux d'incidence pour 100 000 habitants
st.subheader("Taux d'incidence (cas pour 100 000 habitants)")
filtered_copy["incidence_per_100k"] = (
filtered_copy["cases"] / filtered_copy["popData2020"] * 100_000
)
fig_incidence = px.line(
filtered_copy,
x="dateRep",
y="incidence_per_100k",
color="countriesAndTerritories",
)
st.plotly_chart(fig_incidence, use_container_width=True)