Rakesh commited on
Commit
dee9b3a
Β·
verified Β·
1 Parent(s): e091813

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +196 -19
  2. app.py +461 -0
  3. requirements.txt +5 -3
README.md CHANGED
@@ -1,19 +1,196 @@
1
- ---
2
- title: MHI
3
- emoji: πŸš€
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: Streamlit template space
12
- ---
13
-
14
- # Welcome to Streamlit!
15
-
16
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
17
-
18
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
- forums](https://discuss.streamlit.io).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸ₯ Health Parameter Transition Dashboard
2
+
3
+ A comprehensive interactive dashboard for analyzing health parameter transitions between old and new measurements, with location-based filtering capabilities.
4
+
5
+ ## πŸ“Š Features
6
+
7
+ ### Health Parameters Analyzed
8
+ - **HbA1c** - Blood glucose control indicator
9
+ - **LDL** - Low-density lipoprotein cholesterol
10
+ - **BMI** - Body Mass Index
11
+ - **BP** - Blood Pressure
12
+ - **Biometrics** - Overall biometric assessment
13
+ - **MHI** - Mental Health Index
14
+
15
+ ### Dashboard Capabilities
16
+ - **Transition Analysis**: Compare old vs new health parameter tags (Red/Orange/Green)
17
+ - **Location Filtering**: Filter analysis by shared location
18
+ - **Interactive Visualizations**:
19
+ - Transition heatmaps
20
+ - Sankey flow diagrams
21
+ - Summary bar charts
22
+ - **Key Metrics**:
23
+ - Improvement rates
24
+ - Decline rates
25
+ - Stability rates
26
+ - User counts per parameter
27
+ - **Export Functionality**: Download summary reports as CSV files
28
+
29
+ ### Tag Classification System
30
+ - 🟒 **Green**: Optimal/Good health status
31
+ - 🟑 **Orange**: Sub-optimal/Warning status
32
+ - πŸ”΄ **Red**: Alert/Poor health status
33
+
34
+ ## πŸš€ Quick Start
35
+
36
+ ### Prerequisites
37
+ - Python 3.7 or higher
38
+ - pip package manager
39
+
40
+ ### Installation
41
+
42
+ 1. **Clone or download the project files**
43
+ ```bash
44
+ # Ensure you have these files in your directory:
45
+ # - health_dashboard.py
46
+ # - run_dashboard.py
47
+ # - requirements.txt
48
+ # - Combines 2,3,7,9,11(Sheet1).csv
49
+ ```
50
+
51
+ 2. **Install required packages**
52
+ ```bash
53
+ pip install -r requirements.txt
54
+ ```
55
+
56
+ 3. **Run the dashboard**
57
+ ```bash
58
+ python run_dashboard.py
59
+ ```
60
+
61
+ Or directly with Streamlit:
62
+ ```bash
63
+ streamlit run health_dashboard.py
64
+ ```
65
+
66
+ 4. **Access the dashboard**
67
+ - Open your web browser and go to: `http://localhost:8501`
68
+ - The dashboard will automatically load with your data
69
+
70
+ ## πŸ“ˆ Using the Dashboard
71
+
72
+ ### 1. Location Filter
73
+ - Use the sidebar to select a specific location or view "All Locations"
74
+ - The dashboard will update all visualizations based on your selection
75
+
76
+ ### 2. Overall Summary
77
+ - View key metrics at the top: total users, average improvement/decline rates
78
+ - See the summary chart showing transition rates across all parameters
79
+
80
+ ### 3. Parameter-wise Analysis
81
+ - Navigate through tabs for each health parameter
82
+ - Each tab shows:
83
+ - **Metrics**: User counts and transition statistics
84
+ - **Heatmap**: Visual transition matrix
85
+ - **Sankey Diagram**: Flow visualization of transitions
86
+ - **Detailed Table**: Raw transition data
87
+
88
+ ### 4. Key Insights
89
+ - Automatically generated insights based on the data
90
+ - Highlights parameters with excellent improvement or concerning decline rates
91
+
92
+ ### 5. Export Data
93
+ - Click "Generate Summary Report" to create downloadable CSV files
94
+ - Reports include all transition statistics by parameter
95
+
96
+ ## πŸ“Š Understanding the Visualizations
97
+
98
+ ### Transition Heatmap
99
+ - **Rows**: Old health status
100
+ - **Columns**: New health status
101
+ - **Values**: Number of users who transitioned
102
+ - **Colors**: Intensity indicates frequency of transitions
103
+
104
+ ### Sankey Diagram
105
+ - **Left side**: Old status distribution
106
+ - **Right side**: New status distribution
107
+ - **Flows**: Show movement between statuses
108
+ - **Width**: Proportional to number of users
109
+
110
+ ### Summary Charts
111
+ - **Stacked bars**: Show percentage breakdown of improvements/declines/stable
112
+ - **Colors**: Green (improved), Red (declined), Orange (stable)
113
+
114
+ ## πŸ” Data Requirements
115
+
116
+ The dashboard expects a CSV file with the following columns:
117
+ - `Location Shared`: Location information for filtering
118
+ - Health parameter columns (old and new tags):
119
+ - `Hba1c tag old`, `Hba1c tag`
120
+ - `LDLtag old`, `LDLtag`
121
+ - `BMItag old`, `BMItag`
122
+ - `Bptag old`, `Bptag`
123
+ - `biometric tag old`, `biometric tag`
124
+ - `MHI old`, `MHI NEW`
125
+
126
+ ## πŸ› οΈ Technical Details
127
+
128
+ ### Dependencies
129
+ - **Streamlit**: Web application framework
130
+ - **Pandas**: Data manipulation and analysis
131
+ - **Plotly**: Interactive visualizations
132
+ - **NumPy**: Numerical computations
133
+
134
+ ### Performance Features
135
+ - Data caching for faster load times
136
+ - Responsive design for various screen sizes
137
+ - Efficient transition calculations
138
+
139
+ ## πŸ“ Interpreting Results
140
+
141
+ ### Improvement Indicators
142
+ - **Green β†’ Green**: Maintained optimal status
143
+ - **Orange β†’ Green**: Improved from sub-optimal to optimal
144
+ - **Red β†’ Orange/Green**: Improved from alert status
145
+
146
+ ### Decline Indicators
147
+ - **Green οΏ½οΏ½ Orange/Red**: Declined from optimal status
148
+ - **Orange β†’ Red**: Declined from sub-optimal to alert
149
+
150
+ ### Key Metrics
151
+ - **Improvement Rate**: Percentage of users who moved to better health status
152
+ - **Decline Rate**: Percentage of users who moved to worse health status
153
+ - **Stable Rate**: Percentage of users who maintained the same status
154
+
155
+ ## 🎯 Use Cases
156
+
157
+ 1. **Health Program Evaluation**: Assess effectiveness of health interventions
158
+ 2. **Location-based Analysis**: Compare health outcomes across different locations
159
+ 3. **Parameter-specific Insights**: Identify which health areas need attention
160
+ 4. **Trend Monitoring**: Track health improvements or declines over time
161
+ 5. **Resource Allocation**: Focus resources on parameters with high decline rates
162
+
163
+ ## πŸ”§ Troubleshooting
164
+
165
+ ### Common Issues
166
+
167
+ 1. **Data file not found**
168
+ - Ensure `Combines 2,3,7,9,11(Sheet1).csv` is in the same directory
169
+ - Check file name spelling and extension
170
+
171
+ 2. **Missing packages**
172
+ - Run: `pip install -r requirements.txt`
173
+ - Ensure you have Python 3.7+ installed
174
+
175
+ 3. **Dashboard won't load**
176
+ - Check if port 8501 is available
177
+ - Try: `streamlit run health_dashboard.py --server.port 8502`
178
+
179
+ 4. **No data showing**
180
+ - Verify your CSV has the required columns
181
+ - Check that location filter includes your data
182
+
183
+ ## πŸ“ž Support
184
+
185
+ For issues or questions:
186
+ 1. Check the troubleshooting section above
187
+ 2. Verify your data format matches the requirements
188
+ 3. Ensure all dependencies are properly installed
189
+
190
+ ## πŸ“„ License
191
+
192
+ This dashboard is provided as-is for health data analysis purposes.
193
+
194
+ ---
195
+
196
+ **Made with ❀️ for better health outcomes**
app.py ADDED
@@ -0,0 +1,461 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ import plotly.graph_objects as go
5
+ from plotly.subplots import make_subplots
6
+ import numpy as np
7
+
8
+ # Set page config
9
+ st.set_page_config(
10
+ page_title="Health Parameter Transition Dashboard",
11
+ page_icon="πŸ₯",
12
+ layout="wide",
13
+ initial_sidebar_state="expanded"
14
+ )
15
+
16
+ # Custom CSS for better styling
17
+ st.markdown("""
18
+ <style>
19
+ .main-header {
20
+ font-size: 2.5rem;
21
+ font-weight: bold;
22
+ color: #1f77b4;
23
+ text-align: center;
24
+ margin-bottom: 2rem;
25
+ }
26
+
27
+ .metric-card {
28
+ background-color: #f0f2f6;
29
+ padding: 1rem;
30
+ border-radius: 0.5rem;
31
+ border-left: 4px solid #1f77b4;
32
+ }
33
+
34
+ .improvement {
35
+ color: #2ca02c;
36
+ font-weight: bold;
37
+ }
38
+
39
+ .decline {
40
+ color: #d62728;
41
+ font-weight: bold;
42
+ }
43
+
44
+ .stable {
45
+ color: #ff7f0e;
46
+ font-weight: bold;
47
+ }
48
+ </style>
49
+ """, unsafe_allow_html=True)
50
+
51
+ @st.cache_data
52
+ def load_data():
53
+ """Load and preprocess the health data"""
54
+ try:
55
+ df = pd.read_csv("Combines 2,3,7,9,11(Sheet1).csv")
56
+ return df
57
+ except Exception as e:
58
+ st.error(f"Error loading data: {e}")
59
+ return None
60
+
61
+ def clean_tag_data(df):
62
+ """Clean and standardize tag data"""
63
+ # Define health parameters with their old and new tag columns
64
+ health_params = {
65
+ 'HbA1c': {'old_tag': 'Hba1c tag old', 'new_tag': 'Hba1c tag'},
66
+ 'LDL': {'old_tag': 'LDLtag old', 'new_tag': 'LDLtag'},
67
+ 'BMI': {'old_tag': 'BMItag old', 'new_tag': 'BMItag'},
68
+ 'BP': {'old_tag': 'Bptag old', 'new_tag': 'Bptag'},
69
+ 'Biometrics': {'old_tag': 'biometric tag old', 'new_tag': 'biometric tag'},
70
+ 'MHI': {'old_tag': 'MHI old', 'new_tag': 'MHI NEW'}
71
+ }
72
+
73
+ # Clean the data
74
+ for param, cols in health_params.items():
75
+ # Fill NaN values with 'Not Available'
76
+ df[cols['old_tag']] = df[cols['old_tag']].fillna('Not Available')
77
+ df[cols['new_tag']] = df[cols['new_tag']].fillna('Not Available')
78
+
79
+ # Standardize tag values
80
+ for col in [cols['old_tag'], cols['new_tag']]:
81
+ df[col] = df[col].astype(str).str.strip().str.title()
82
+ # Map common variations
83
+ df[col] = df[col].replace({
84
+ 'Alert': 'Red',
85
+ 'Sub-Optimal': 'Orange',
86
+ 'Optimal': 'Green',
87
+ 'Suboptimal': 'Orange',
88
+ '0': 'Not Available',
89
+ '': 'Not Available'
90
+ })
91
+
92
+ return df, health_params
93
+
94
+ def calculate_transitions(df, health_params, location_filter=None):
95
+ """Calculate transition matrices for each health parameter"""
96
+ if location_filter and location_filter != "All Locations":
97
+ df_filtered = df[df['Location Shared'] == location_filter].copy()
98
+ else:
99
+ df_filtered = df.copy()
100
+
101
+ transitions = {}
102
+
103
+ for param, cols in health_params.items():
104
+ old_col = cols['old_tag']
105
+ new_col = cols['new_tag']
106
+
107
+ # Create transition matrix
108
+ transition_df = df_filtered[[old_col, new_col]].copy()
109
+ transition_df = transition_df[
110
+ (transition_df[old_col] != 'Not Available') &
111
+ (transition_df[new_col] != 'Not Available')
112
+ ]
113
+
114
+ if len(transition_df) > 0:
115
+ transition_matrix = pd.crosstab(
116
+ transition_df[old_col],
117
+ transition_df[new_col],
118
+ margins=True
119
+ )
120
+
121
+ # Calculate transition summary
122
+ total_users = len(transition_df)
123
+
124
+ # Count improvements, declines, and stable
125
+ improved = 0
126
+ declined = 0
127
+ stable = 0
128
+
129
+ tag_hierarchy = {'Red': 3, 'Orange': 2, 'Green': 1}
130
+
131
+ for _, row in transition_df.iterrows():
132
+ old_val = row[old_col]
133
+ new_val = row[new_col]
134
+
135
+ if old_val in tag_hierarchy and new_val in tag_hierarchy:
136
+ old_score = tag_hierarchy[old_val]
137
+ new_score = tag_hierarchy[new_val]
138
+
139
+ if new_score < old_score: # Lower score is better
140
+ improved += 1
141
+ elif new_score > old_score:
142
+ declined += 1
143
+ else:
144
+ stable += 1
145
+
146
+ transitions[param] = {
147
+ 'matrix': transition_matrix,
148
+ 'total_users': total_users,
149
+ 'improved': improved,
150
+ 'declined': declined,
151
+ 'stable': stable,
152
+ 'improvement_rate': (improved / total_users * 100) if total_users > 0 else 0,
153
+ 'decline_rate': (declined / total_users * 100) if total_users > 0 else 0,
154
+ 'stable_rate': (stable / total_users * 100) if total_users > 0 else 0
155
+ }
156
+
157
+ return transitions
158
+
159
+ def create_transition_heatmap(transition_matrix, param_name):
160
+ """Create a heatmap for transition matrix"""
161
+ # Remove the 'All' row and column for cleaner visualization
162
+ matrix_clean = transition_matrix.drop('All', axis=0).drop('All', axis=1)
163
+
164
+ fig = px.imshow(
165
+ matrix_clean.values,
166
+ x=matrix_clean.columns,
167
+ y=matrix_clean.index,
168
+ color_continuous_scale='Blues',
169
+ aspect="auto",
170
+ title=f"{param_name} Transition Matrix"
171
+ )
172
+
173
+ # Add text annotations
174
+ for i, row in enumerate(matrix_clean.index):
175
+ for j, col in enumerate(matrix_clean.columns):
176
+ fig.add_annotation(
177
+ x=j, y=i,
178
+ text=str(matrix_clean.loc[row, col]),
179
+ showarrow=False,
180
+ font=dict(color="white" if matrix_clean.loc[row, col] > matrix_clean.values.max()/2 else "black")
181
+ )
182
+
183
+ fig.update_layout(
184
+ xaxis_title="New Status",
185
+ yaxis_title="Old Status",
186
+ height=400
187
+ )
188
+
189
+ return fig
190
+
191
+ def create_summary_chart(transitions):
192
+ """Create summary chart showing improvement/decline rates"""
193
+ params = list(transitions.keys())
194
+ improvement_rates = [transitions[p]['improvement_rate'] for p in params]
195
+ decline_rates = [transitions[p]['decline_rate'] for p in params]
196
+ stable_rates = [transitions[p]['stable_rate'] for p in params]
197
+
198
+ fig = go.Figure()
199
+
200
+ fig.add_trace(go.Bar(
201
+ name='Improved',
202
+ x=params,
203
+ y=improvement_rates,
204
+ marker_color='#2ca02c'
205
+ ))
206
+
207
+ fig.add_trace(go.Bar(
208
+ name='Declined',
209
+ x=params,
210
+ y=decline_rates,
211
+ marker_color='#d62728'
212
+ ))
213
+
214
+ fig.add_trace(go.Bar(
215
+ name='Stable',
216
+ x=params,
217
+ y=stable_rates,
218
+ marker_color='#ff7f0e'
219
+ ))
220
+
221
+ fig.update_layout(
222
+ title="Health Parameter Transition Summary",
223
+ xaxis_title="Health Parameters",
224
+ yaxis_title="Percentage of Users",
225
+ barmode='stack',
226
+ height=500
227
+ )
228
+
229
+ return fig
230
+
231
+ def create_sankey_diagram(df, param, old_col, new_col, location_filter=None):
232
+ """Create Sankey diagram for parameter transitions"""
233
+ if location_filter and location_filter != "All Locations":
234
+ df_filtered = df[df['Location Shared'] == location_filter].copy()
235
+ else:
236
+ df_filtered = df.copy()
237
+
238
+ # Filter out 'Not Available' values
239
+ df_filtered = df_filtered[
240
+ (df_filtered[old_col] != 'Not Available') &
241
+ (df_filtered[new_col] != 'Not Available')
242
+ ]
243
+
244
+ if len(df_filtered) == 0:
245
+ return None
246
+
247
+ # Create transition counts
248
+ transitions = df_filtered.groupby([old_col, new_col]).size().reset_index(name='count')
249
+
250
+ # Create unique labels
251
+ all_labels = list(set(transitions[old_col].tolist() + transitions[new_col].tolist()))
252
+ label_map = {label: i for i, label in enumerate(all_labels)}
253
+
254
+ # Prepare data for Sankey
255
+ source = [label_map[old] for old in transitions[old_col]]
256
+ target = [label_map[new] + len(set(transitions[old_col])) for new in transitions[new_col]]
257
+ values = transitions['count'].tolist()
258
+
259
+ # Create color mapping
260
+ color_map = {'Green': '#2ca02c', 'Orange': '#ff7f0e', 'Red': '#d62728'}
261
+ node_colors = [color_map.get(label, '#1f77b4') for label in all_labels]
262
+
263
+ fig = go.Figure(data=[go.Sankey(
264
+ node=dict(
265
+ pad=15,
266
+ thickness=20,
267
+ line=dict(color="black", width=0.5),
268
+ label=[f"{label} (Old)" if i < len(set(transitions[old_col])) else f"{label} (New)"
269
+ for i, label in enumerate(all_labels + all_labels)],
270
+ color=node_colors + node_colors
271
+ ),
272
+ link=dict(
273
+ source=source,
274
+ target=target,
275
+ value=values
276
+ )
277
+ )])
278
+
279
+ fig.update_layout(
280
+ title_text=f"{param} Parameter Transitions",
281
+ font_size=10,
282
+ height=400
283
+ )
284
+
285
+ return fig
286
+
287
+ def main():
288
+ st.markdown('<h1 class="main-header">πŸ₯ Health Parameter Transition Dashboard</h1>', unsafe_allow_html=True)
289
+
290
+ # Add description
291
+ st.markdown("""
292
+ This dashboard analyzes health parameter transitions between old and new measurements.
293
+ It tracks improvements, declines, and stability across different health metrics with location-based filtering.
294
+
295
+ **Health Parameters Analyzed:**
296
+ - **HbA1c**: Blood glucose control indicator
297
+ - **LDL**: Low-density lipoprotein cholesterol
298
+ - **BMI**: Body Mass Index
299
+ - **BP**: Blood Pressure
300
+ - **Biometrics**: Overall biometric assessment
301
+ - **MHI**: Mental Health Index
302
+ """)
303
+
304
+ # Load data
305
+ df = load_data()
306
+ if df is None:
307
+ st.error("Unable to load data. Please check if the data file is available.")
308
+ st.stop()
309
+
310
+ # Clean data
311
+ df_clean, health_params = clean_tag_data(df)
312
+
313
+ # Sidebar for filters
314
+ st.sidebar.header("πŸ“Š Dashboard Filters")
315
+
316
+ # Location filter
317
+ locations = ['All Locations'] + sorted(df_clean['Location Shared'].dropna().unique().tolist())
318
+ selected_location = st.sidebar.selectbox("Select Location", locations)
319
+
320
+ # Calculate transitions
321
+ transitions = calculate_transitions(df_clean, health_params, selected_location)
322
+
323
+ # Display summary metrics
324
+ st.header("πŸ“ˆ Overall Summary")
325
+
326
+ if selected_location != "All Locations":
327
+ st.info(f"πŸ“ Showing data for: **{selected_location}**")
328
+
329
+ # Create columns for summary metrics
330
+ col1, col2, col3, col4 = st.columns(4)
331
+
332
+ total_users = sum([t['total_users'] for t in transitions.values()]) // len(transitions) if transitions else 0
333
+ avg_improvement = np.mean([t['improvement_rate'] for t in transitions.values()]) if transitions else 0
334
+ avg_decline = np.mean([t['decline_rate'] for t in transitions.values()]) if transitions else 0
335
+ avg_stable = np.mean([t['stable_rate'] for t in transitions.values()]) if transitions else 0
336
+
337
+ with col1:
338
+ st.metric("Total Users Analyzed", f"{total_users:,}")
339
+
340
+ with col2:
341
+ st.metric("Average Improvement Rate", f"{avg_improvement:.1f}%",
342
+ delta=f"+{avg_improvement:.1f}%" if avg_improvement > 0 else None)
343
+
344
+ with col3:
345
+ st.metric("Average Decline Rate", f"{avg_decline:.1f}%",
346
+ delta=f"-{avg_decline:.1f}%" if avg_decline > 0 else None)
347
+
348
+ with col4:
349
+ st.metric("Average Stable Rate", f"{avg_stable:.1f}%")
350
+
351
+ # Summary chart
352
+ if transitions:
353
+ st.plotly_chart(create_summary_chart(transitions), use_container_width=True)
354
+
355
+ # Parameter-wise analysis
356
+ st.header("πŸ” Parameter-wise Analysis")
357
+
358
+ if transitions:
359
+ tabs = st.tabs(list(health_params.keys()))
360
+
361
+ for i, (param, cols) in enumerate(health_params.items()):
362
+ with tabs[i]:
363
+ if param in transitions and transitions[param]['total_users'] > 0:
364
+ col1, col2 = st.columns([1, 1])
365
+
366
+ with col1:
367
+ # Display metrics for this parameter
368
+ st.subheader(f"{param} Metrics")
369
+
370
+ metrics_col1, metrics_col2, metrics_col3 = st.columns(3)
371
+
372
+ with metrics_col1:
373
+ st.metric("Users", transitions[param]['total_users'])
374
+
375
+ with metrics_col2:
376
+ improvement_rate = transitions[param]['improvement_rate']
377
+ st.metric("Improved", f"{transitions[param]['improved']}",
378
+ f"{improvement_rate:.1f}%")
379
+
380
+ with metrics_col3:
381
+ decline_rate = transitions[param]['decline_rate']
382
+ st.metric("Declined", f"{transitions[param]['declined']}",
383
+ f"{decline_rate:.1f}%")
384
+
385
+ # Transition matrix heatmap
386
+ st.plotly_chart(
387
+ create_transition_heatmap(transitions[param]['matrix'], param),
388
+ use_container_width=True
389
+ )
390
+
391
+ with col2:
392
+ # Sankey diagram
393
+ sankey_fig = create_sankey_diagram(
394
+ df_clean, param, cols['old_tag'], cols['new_tag'], selected_location
395
+ )
396
+ if sankey_fig:
397
+ st.plotly_chart(sankey_fig, use_container_width=True)
398
+ else:
399
+ st.info("No transition data available for Sankey diagram")
400
+
401
+ # Detailed transition table
402
+ st.subheader(f"{param} Detailed Transitions")
403
+ transition_table = transitions[param]['matrix']
404
+ st.dataframe(transition_table, use_container_width=True)
405
+
406
+ else:
407
+ st.warning(f"No data available for {param} parameter")
408
+ else:
409
+ st.warning("No transition data available for the selected location.")
410
+
411
+ # Data insights
412
+ st.header("πŸ’‘ Key Insights")
413
+
414
+ insights = []
415
+
416
+ for param, data in transitions.items():
417
+ if data['total_users'] > 0:
418
+ if data['improvement_rate'] > 50:
419
+ insights.append(f"βœ… **{param}**: Excellent improvement rate of {data['improvement_rate']:.1f}%")
420
+ elif data['improvement_rate'] > 30:
421
+ insights.append(f"🟑 **{param}**: Good improvement rate of {data['improvement_rate']:.1f}%")
422
+
423
+ if data['decline_rate'] > 30:
424
+ insights.append(f"⚠️ **{param}**: High decline rate of {data['decline_rate']:.1f}% - needs attention")
425
+
426
+ if insights:
427
+ for insight in insights:
428
+ st.markdown(insight)
429
+ else:
430
+ st.info("No significant insights to highlight at this time.")
431
+
432
+ # Export functionality
433
+ st.header("πŸ“₯ Export Data")
434
+
435
+ if st.button("Generate Summary Report"):
436
+ summary_data = []
437
+ for param, data in transitions.items():
438
+ summary_data.append({
439
+ 'Parameter': param,
440
+ 'Total Users': data['total_users'],
441
+ 'Improved': data['improved'],
442
+ 'Declined': data['declined'],
443
+ 'Stable': data['stable'],
444
+ 'Improvement Rate (%)': round(data['improvement_rate'], 2),
445
+ 'Decline Rate (%)': round(data['decline_rate'], 2),
446
+ 'Stable Rate (%)': round(data['stable_rate'], 2)
447
+ })
448
+
449
+ summary_df = pd.DataFrame(summary_data)
450
+
451
+ st.download_button(
452
+ label="Download Summary CSV",
453
+ data=summary_df.to_csv(index=False),
454
+ file_name=f"health_transitions_summary_{selected_location.replace(' ', '_')}.csv",
455
+ mime="text/csv"
456
+ )
457
+
458
+ st.dataframe(summary_df, use_container_width=True)
459
+
460
+ if __name__ == "__main__":
461
+ main()
requirements.txt CHANGED
@@ -1,3 +1,5 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
1
+ streamlit>=1.28.0
2
+ pandas>=2.0.0
3
+ plotly>=5.15.0
4
+ numpy>=1.24.0
5
+ openpyxl>=3.1.0