Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import numpy as np
|
4 |
+
import matplotlib.pyplot as plt
|
5 |
+
import seaborn as sns
|
6 |
+
import plotly.express as px
|
7 |
+
from datetime import datetime, timedelta
|
8 |
+
|
9 |
+
# Set page config
|
10 |
+
st.set_page_config(page_title="Healthcare Dashboard", layout="wide")
|
11 |
+
|
12 |
+
# Load sample data (replace this with your actual data loading logic)
|
13 |
+
@st.cache_data
|
14 |
+
def load_data():
|
15 |
+
# Generate sample data
|
16 |
+
np.random.seed(42)
|
17 |
+
dates = pd.date_range(start="2022-01-01", end="2023-04-30", freq="D")
|
18 |
+
departments = ["Cardiology", "Neurology", "Oncology", "Pediatrics", "Emergency"]
|
19 |
+
diagnoses = ["Hypertension", "Stroke", "Cancer", "Diabetes", "Pneumonia", "Fracture", "Appendicitis", "Asthma", "Heart Disease", "Influenza"]
|
20 |
+
|
21 |
+
data = {
|
22 |
+
"Date": np.random.choice(dates, 1000),
|
23 |
+
"Patient ID": np.arange(1, 1001),
|
24 |
+
"Age": np.random.randint(1, 100, 1000),
|
25 |
+
"Gender": np.random.choice(["Male", "Female"], 1000),
|
26 |
+
"Department": np.random.choice(departments, 1000),
|
27 |
+
"Diagnosis": np.random.choice(diagnoses, 1000),
|
28 |
+
"Length of Stay": np.random.randint(1, 30, 1000)
|
29 |
+
}
|
30 |
+
|
31 |
+
return pd.DataFrame(data)
|
32 |
+
|
33 |
+
df = load_data()
|
34 |
+
|
35 |
+
# Title and introduction
|
36 |
+
st.title("Healthcare Dashboard")
|
37 |
+
st.write("Welcome to the healthcare dashboard. This interactive tool provides insights into patient data, hospital admissions, and key healthcare metrics.")
|
38 |
+
|
39 |
+
# Sidebar
|
40 |
+
st.sidebar.header("Filters")
|
41 |
+
department = st.sidebar.multiselect("Select Department", options=df["Department"].unique(), default=df["Department"].unique())
|
42 |
+
date_range = st.sidebar.date_input("Select Date Range", value=(df["Date"].min().date(), df["Date"].max().date()))
|
43 |
+
|
44 |
+
# Convert date_range to datetime
|
45 |
+
start_date = datetime.combine(date_range[0], datetime.min.time())
|
46 |
+
end_date = datetime.combine(date_range[1], datetime.max.time())
|
47 |
+
|
48 |
+
# Filter data based on user selection
|
49 |
+
filtered_df = df[(df["Department"].isin(department)) & (df["Date"] >= start_date) & (df["Date"] <= end_date)]
|
50 |
+
|
51 |
+
# Main content
|
52 |
+
col1, col2 = st.columns(2)
|
53 |
+
|
54 |
+
# Patient Demographics
|
55 |
+
with col1:
|
56 |
+
st.subheader("Patient Demographics")
|
57 |
+
fig_gender = px.pie(filtered_df, names="Gender", title="Gender Distribution")
|
58 |
+
st.plotly_chart(fig_gender, use_container_width=True)
|
59 |
+
|
60 |
+
# Hospital Admissions Over Time
|
61 |
+
with col2:
|
62 |
+
st.subheader("Hospital Admissions Over Time")
|
63 |
+
admissions_over_time = filtered_df.groupby("Date").size().reset_index(name="Admissions")
|
64 |
+
fig_admissions = px.line(admissions_over_time, x="Date", y="Admissions", title="Daily Hospital Admissions")
|
65 |
+
st.plotly_chart(fig_admissions, use_container_width=True)
|
66 |
+
|
67 |
+
# Top 10 Diagnoses
|
68 |
+
st.subheader("Top 10 Diagnoses")
|
69 |
+
top_diagnoses = filtered_df["Diagnosis"].value_counts().nlargest(10)
|
70 |
+
fig_diagnoses = px.bar(top_diagnoses, x=top_diagnoses.index, y=top_diagnoses.values, title="Top 10 Diagnoses")
|
71 |
+
st.plotly_chart(fig_diagnoses, use_container_width=True)
|
72 |
+
|
73 |
+
# Average Length of Stay by Department
|
74 |
+
st.subheader("Average Length of Stay by Department")
|
75 |
+
avg_los = filtered_df.groupby("Department")["Length of Stay"].mean().sort_values(ascending=True)
|
76 |
+
fig_los = px.bar(avg_los, x=avg_los.values, y=avg_los.index, orientation="h", title="Average Length of Stay (Days)")
|
77 |
+
st.plotly_chart(fig_los, use_container_width=True)
|
78 |
+
|
79 |
+
# Age Distribution
|
80 |
+
st.subheader("Age Distribution")
|
81 |
+
fig_age = px.histogram(filtered_df, x="Age", nbins=20, title="Age Distribution of Patients")
|
82 |
+
st.plotly_chart(fig_age, use_container_width=True)
|
83 |
+
|
84 |
+
# Interactive Data Table
|
85 |
+
st.subheader("Patient Data")
|
86 |
+
st.dataframe(filtered_df)
|
87 |
+
|
88 |
+
# Add a download button for the filtered data
|
89 |
+
csv = filtered_df.to_csv(index=False).encode('utf-8')
|
90 |
+
st.download_button(
|
91 |
+
label="Download data as CSV",
|
92 |
+
data=csv,
|
93 |
+
file_name="healthcare_data.csv",
|
94 |
+
mime="text/csv",
|
95 |
+
)
|
96 |
+
|
97 |
+
# Key Metrics
|
98 |
+
st.subheader("Key Metrics")
|
99 |
+
col1, col2, col3, col4 = st.columns(4)
|
100 |
+
col1.metric("Total Patients", len(filtered_df))
|
101 |
+
col2.metric("Avg. Length of Stay", f"{filtered_df['Length of Stay'].mean():.2f} days")
|
102 |
+
col3.metric("Most Common Diagnosis", filtered_df["Diagnosis"].mode()[0])
|
103 |
+
col4.metric("Busiest Department", filtered_df["Department"].value_counts().index[0])
|