Skip to content

Commit 655795c

Browse files
committed
Dashboard with summary data
1 parent d221710 commit 655795c

File tree

2 files changed

+61
-57
lines changed

2 files changed

+61
-57
lines changed

apps/viz/dash/inventory_dashboard/app.py

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import logging
2-
31
import dash_bootstrap_components as dbc
2+
import pandas as pd
43
import plotly.express as px
54
from dash import dash_table, dcc, html
65
from dash.dependencies import Input, Output
@@ -12,8 +11,6 @@
1211
unique_countries = sorted(clean_livelihood_data["country_code"].dropna().unique())
1312
unique_zones = sorted(clean_livelihood_data["livelihood_zone_baseline_label"].dropna().unique())
1413

15-
logger = logging.getLogger(__name__)
16-
1714
# Dash app
1815
app = DjangoDash("Inventory_dashboard", suppress_callback_exceptions=True, external_stylesheets=[dbc.themes.BOOTSTRAP])
1916
app.title = "HEA Dashboard"
@@ -29,18 +26,18 @@
2926
dcc.Dropdown(
3027
id="country-dropdown",
3128
options=[{"label": country, "value": country} for country in unique_countries],
32-
placeholder="Select Country(s)",
29+
placeholder=f"Select Country(s) (e.g., {unique_countries[0]})",
3330
multi=True,
3431
),
3532
],
36-
style={"flex": "1", "marginRight": "10px"}, # Set flex and spacing
33+
style={"flex": "1", "marginRight": "10px"},
3734
),
3835
html.Div(
3936
[
4037
dcc.Dropdown(
4138
id="livelihood-zone-dropdown",
4239
options=[{"label": zone, "value": zone} for zone in unique_zones],
43-
placeholder="Select Livelihood Zone(s)",
40+
placeholder=f"Select Livelihood Zone(s) (e.g., {unique_zones[0]})",
4441
multi=True,
4542
),
4643
],
@@ -77,12 +74,22 @@
7774
id="data-table",
7875
columns=[
7976
{"name": "Livelihood Zone", "id": "livelihood_zone_baseline_label"},
80-
{"name": "Strategy Type Count", "id": "Count"},
81-
{"name": "Wealth Characteristics Count", "id": "Wealth Characteristics Count"},
77+
{"name": "Total Strategy Type Count", "id": "Strategy Type Count"},
78+
{"name": "Summary Wealth Characteristics", "id": "Summary Data"},
79+
{"name": "Community Wealth Characteristics", "id": "Community Data"},
8280
],
8381
style_table={"overflowX": "auto"},
84-
style_cell={"textAlign": "left"},
85-
page_size=12,
82+
style_cell={
83+
"textAlign": "left",
84+
"fontSize": "15px", # Increase font size
85+
"padding": "10px", # Add padding
86+
},
87+
style_header={
88+
"fontSize": "18px", # Increase font size for header
89+
"fontWeight": "bold", # Make header bold
90+
"textAlign": "center",
91+
},
92+
page_size=10,
8693
),
8794
],
8895
className="inventory-filter inventory-filter-last",
@@ -124,63 +131,74 @@ def update_charts(selected_countries, selected_zones):
124131
]
125132
filtered_wealth = filtered_wealth[filtered_wealth["livelihood_zone_baseline_label"].isin(selected_zones)]
126133

127-
# Group data for charts
134+
# Group and aggregate Strategy Type Count
128135
livelihood_grouped = (
129136
filtered_livelihood.groupby(["livelihood_zone_baseline_label", "strategy_type_label"])
130137
.size()
131-
.reset_index(name="Count")
138+
.reset_index(name="Strategy Type Count")
132139
)
133-
wealth_grouped = (
134-
filtered_wealth.groupby("livelihood_zone_baseline_label")
135-
.size()
136-
.reset_index(name="Wealth Characteristics Count")
140+
livelihood_summary = (
141+
livelihood_grouped.groupby("livelihood_zone_baseline_label")["Strategy Type Count"].sum().reset_index()
137142
)
138-
wealth_monthly_grouped = (
139-
filtered_wealth.groupby(["created_month", "livelihood_zone_baseline_label"])
143+
144+
# Group and pivot Wealth Characteristics Count
145+
wealth_grouped = (
146+
filtered_wealth.groupby(["livelihood_zone_baseline_label", "Record Type"])
140147
.size()
141148
.reset_index(name="Wealth Characteristics Count")
142149
)
143-
150+
wealth_grouped_pivot = wealth_grouped.pivot_table(
151+
index="livelihood_zone_baseline_label",
152+
columns="Record Type",
153+
values="Wealth Characteristics Count",
154+
aggfunc="sum",
155+
fill_value=0,
156+
).reset_index()
157+
158+
# Merge livelihood and wealth data
159+
merged_data = pd.merge(livelihood_summary, wealth_grouped_pivot, on="livelihood_zone_baseline_label", how="left")
160+
161+
# Create charts
144162
wealth_fig = px.bar(
145163
wealth_grouped,
146164
x="livelihood_zone_baseline_label",
147165
y="Wealth Characteristics Count",
148-
title="Wealth Characteristics per Baseline",
166+
color="Record Type",
167+
barmode="stack",
168+
title="Wealth Characteristics by Type",
149169
labels={
150-
"livelihood_zone_baseline_label": "Baseline",
151-
"Wealth Characteristics Count": "No. of Wealth Characteristics",
170+
"livelihood_zone_baseline_label": "Livelihood Zone",
152171
},
153172
)
154173

155174
livelihood_fig = px.bar(
156175
livelihood_grouped,
157176
x="strategy_type_label",
158-
y="Count",
177+
y="Strategy Type Count",
159178
color="livelihood_zone_baseline_label",
160-
title="Livelihood Strategies per Baseline",
179+
barmode="stack",
180+
title="Strategy Types by Baseline",
161181
labels={
162182
"strategy_type_label": "Strategy Type",
163-
"Count": "No. of Livelihood Strategies",
164-
"livelihood_zone_baseline_label": "Baseline",
183+
"livelihood_zone_baseline_label": "Baseline Zone",
165184
},
166185
)
167186

168-
# Stacked/multiple column chart for wealth characteristics by month
169187
wealth_monthly_fig = px.bar(
170-
wealth_monthly_grouped,
188+
filtered_wealth.groupby(["created_month", "Record Type"])
189+
.size()
190+
.reset_index(name="Wealth Characteristics Count"),
171191
x="created_month",
172192
y="Wealth Characteristics Count",
173-
color="livelihood_zone_baseline_label",
174-
barmode="stack", # Use 'group' for multiple column chart
175-
title="Wealth Characteristics by Month and Baseline",
193+
color="Record Type",
194+
barmode="stack",
195+
title="Wealth Characteristics by Month",
176196
labels={
177197
"created_month": "Month",
178-
"Wealth Characteristics Count": "No. of Wealth Characteristics",
179-
"livelihood_zone_baseline_label": "Baseline",
180198
},
181199
)
182200

183-
return zone_options, wealth_fig, livelihood_fig, wealth_monthly_fig, livelihood_grouped.to_dict("records")
201+
return zone_options, wealth_fig, livelihood_fig, wealth_monthly_fig, merged_data.to_dict("records")
184202

185203

186204
# Run the app

apps/viz/dash/inventory_dashboard/functions.py

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -35,41 +35,27 @@ def prepare_wealth_group_data(df):
3535
"""
3636
Prepare wealth group data for visualization.
3737
"""
38-
# Rename columns for consistency
3938
df.rename(columns={"livelihood_zone_country_code": "country_code"}, inplace=True)
4039

41-
# Extract baseline date from 'livelihood_zone_baseline_label'
4240
if "livelihood_zone_baseline_label" in df.columns:
4341
df["ls_baseline_date"] = df["livelihood_zone_baseline_label"].str.split(": ").str[1]
4442
else:
45-
df["ls_baseline_date"] = None # Assign None if the column is missing
43+
df["ls_baseline_date"] = None
4644

47-
# Convert baseline date to datetime and extract the month
4845
df["ls_baseline_month"] = pd.to_datetime(df["ls_baseline_date"], errors="coerce").dt.month
4946

50-
# Define month mapping dictionary
51-
month_mapping = {
52-
1: "January",
53-
2: "February",
54-
3: "March",
55-
4: "April",
56-
5: "May",
57-
6: "June",
58-
7: "July",
59-
8: "August",
60-
9: "September",
61-
10: "October",
62-
11: "November",
63-
12: "December",
64-
}
65-
66-
# Extract 'created_month' from 'created_date' or fallback to 'ls_baseline_date'
47+
month_mapping = {month: pd.Timestamp(f"2023-{month:02}-01").strftime("%B") for month in range(1, 13)}
48+
6749
if "created_date" in df.columns:
6850
df["created_month"] = pd.to_datetime(df["created_date"], errors="coerce").dt.month.map(month_mapping)
6951
else:
70-
print("Warning: 'created_date' column is missing. Using 'ls_baseline_date' instead.")
7152
df["created_month"] = pd.to_datetime(df["ls_baseline_date"], errors="coerce").dt.month.map(month_mapping)
7253

54+
if "community_name" in df.columns:
55+
df["Record Type"] = df["community_name"].apply(lambda x: "Summary Data" if pd.isna(x) else "Community Data")
56+
else:
57+
df["Record Type"] = "Community Data"
58+
7359
return df
7460

7561

0 commit comments

Comments
 (0)