Loosebag commited on
Commit
41555ca
Β·
1 Parent(s): 36dae52

Refine dashboard UI with clean borders, adaptive padding, and consistent graphs

Browse files
Files changed (1) hide show
  1. app.py +93 -73
app.py CHANGED
@@ -125,89 +125,109 @@ with st.sidebar:
125
  st.session_state.cumulative_reward = 0.0
126
 
127
  # ── Main UI ──
128
- st.title("EcoGrid-OpenEnv Dashboard")
129
- st.markdown("RL Environment for Sustainable Energy Grid Management. (Scaler Γ— Meta Hackathon)")
 
130
 
131
  col_live, col_reward, col_emissions = st.columns(3)
132
 
133
  # Panel 1: Live Grid State
134
  with col_live:
135
- st.subheader("Live Grid State")
136
- state = st.session_state.state
137
-
138
- st.metric("Timestep", f"{state.time_step} / {st.session_state.env.get_task_config(st.session_state.current_task)['episode_length']}")
139
-
140
- # Battery Gauge
141
- fig = go.Figure(go.Indicator(
142
- mode = "gauge+number",
143
- value = state.battery_level * 100,
144
- title = {'text': "Battery Level %"},
145
- gauge = {'axis': {'range': [0, 100]}, 'bar': {'color': "green"}}
146
- ))
147
- fig.update_layout(height=200, margin=dict(l=10, r=10, t=30, b=10))
148
- st.plotly_chart(fig, use_container_width=True)
149
-
150
- # Capacity Bars
151
- fig2 = go.Figure(data=[
152
- go.Bar(name='Demand (MWh)', x=['Demand'], y=[state.demand], marker_color='red'),
153
- go.Bar(name='Solar Cap', x=['Solar'], y=[state.solar_capacity * 100], marker_color='orange'),
154
- go.Bar(name='Wind Cap', x=['Wind'], y=[state.wind_capacity * 100], marker_color='blue')
155
- ])
156
- fig2.update_layout(height=250, margin=dict(l=10, r=10, t=10, b=10), barmode='group')
157
- st.plotly_chart(fig2, use_container_width=True)
 
158
 
159
 
160
  # Panel 2: Reward Over Time
161
  with col_reward:
162
- st.subheader("Agent Performance")
163
-
164
- if st.session_state.history:
165
- df = pd.DataFrame(st.session_state.history)
166
-
167
- # Current Episode Reward
168
- fig3 = go.Figure()
169
- fig3.add_trace(go.Scatter(x=df['step'], y=df['reward'], mode='lines+markers', name='Total Reward'))
170
- fig3.update_layout(title="Step Reward", height=200, margin=dict(l=10, r=10, t=30, b=10))
171
- st.plotly_chart(fig3, use_container_width=True)
172
 
173
- # Breakdown
174
- fig4 = go.Figure()
175
- fig4.add_trace(go.Scatter(x=df['step'], y=df['cost_score'], name='Cost Score'))
176
- fig4.add_trace(go.Scatter(x=df['step'], y=df['carbon_score'], name='Carbon Score'))
177
- fig4.add_trace(go.Scatter(x=df['step'], y=df['stability_score'], name='Stability Score'))
178
- fig4.update_layout(title="Reward Breakdown", height=250, margin=dict(l=10, r=10, t=30, b=10))
179
- st.plotly_chart(fig4, use_container_width=True)
180
- else:
181
- st.info("Step the environment to see performance charts.")
 
 
 
 
 
 
 
 
 
 
182
 
183
  # Panel 3: Emissions & Training
184
  with col_emissions:
185
- st.subheader("Training & Emissions")
186
-
187
- # Carbon Budget Gauge
188
- max_budget = st.session_state.env.get_task_config(st.session_state.current_task)['carbon_budget']
189
- current_budget = state.carbon_budget_remaining
190
-
191
- fig5 = go.Figure(go.Indicator(
192
- mode = "gauge+number",
193
- value = current_budget,
194
- title = {'text': "Carbon Budget (kgCO2)"},
195
- gauge = {
196
- 'axis': {'range': [0, max_budget]},
197
- 'bar': {'color': "darkred" if current_budget < max_budget * 0.2 else "green"},
198
- 'steps': [
199
- {'range': [0, max_budget * 0.2], 'color': "lightcoral"}
200
- ]
201
- }
202
- ))
203
- fig5.update_layout(height=200, margin=dict(l=10, r=10, t=30, b=10))
204
- st.plotly_chart(fig5, use_container_width=True)
205
-
206
- # RL Training Curve
207
- st.markdown("**GRPO Training Progress (Unsloth)**")
208
- curve_data = load_or_mock_reward_curve()
209
- df_curve = pd.DataFrame(curve_data)
210
- fig6 = go.Figure()
211
- fig6.add_trace(go.Scatter(x=df_curve['step'], y=df_curve['reward'], mode='lines', line=dict(color='purple', width=3)))
212
- fig6.update_layout(height=220, margin=dict(l=10, r=10, t=10, b=10), xaxis_title="Training Steps", yaxis_title="Avg Reward")
213
- st.plotly_chart(fig6, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  st.session_state.cumulative_reward = 0.0
126
 
127
  # ── Main UI ──
128
+ st.title("⚑ EcoGrid-OpenEnv Dashboard")
129
+ st.markdown("Reinforcement Learning Environment for Sustainable Energy Grid Management. *(Scaler Γ— Meta Hackathon)*")
130
+ st.markdown("---")
131
 
132
  col_live, col_reward, col_emissions = st.columns(3)
133
 
134
  # Panel 1: Live Grid State
135
  with col_live:
136
+ with st.container(border=True):
137
+ st.subheader("πŸ“‘ Live Grid State")
138
+ state = st.session_state.state
139
+
140
+ st.metric("Timestep", f"{state.time_step} / {st.session_state.env.get_task_config(st.session_state.current_task)['episode_length']}")
141
+
142
+ # Battery Gauge
143
+ fig = go.Figure(go.Indicator(
144
+ mode = "gauge+number",
145
+ value = state.battery_level * 100,
146
+ title = {'text': "Battery Level (%)", 'font': {'size': 14}},
147
+ gauge = {'axis': {'range': [0, 100]}, 'bar': {'color': "#00cc96"}, 'bgcolor': "rgba(0,0,0,0)"}
148
+ ))
149
+ fig.update_layout(height=200, margin=dict(l=20, r=20, t=40, b=20))
150
+ st.plotly_chart(fig, use_container_width=True, config={'displayModeBar': False})
151
+
152
+ # Capacity Bars
153
+ fig2 = go.Figure(data=[
154
+ go.Bar(name='Demand', x=['Demand'], y=[state.demand], marker_color='#ef553b'),
155
+ go.Bar(name='Solar', x=['Solar'], y=[state.solar_capacity * 100], marker_color='#ffa15a'),
156
+ go.Bar(name='Wind', x=['Wind'], y=[state.wind_capacity * 100], marker_color='#636efa')
157
+ ])
158
+ fig2.update_layout(height=220, margin=dict(l=20, r=20, t=20, b=20), barmode='group', showlegend=False)
159
+ st.plotly_chart(fig2, use_container_width=True, config={'displayModeBar': False})
160
 
161
 
162
  # Panel 2: Reward Over Time
163
  with col_reward:
164
+ with st.container(border=True):
165
+ st.subheader("πŸ“ˆ Agent Performance")
 
 
 
 
 
 
 
 
166
 
167
+ if st.session_state.history:
168
+ df = pd.DataFrame(st.session_state.history)
169
+
170
+ # Current Episode Reward
171
+ fig3 = go.Figure()
172
+ fig3.add_trace(go.Scatter(x=df['step'], y=df['reward'], mode='lines', fill='tozeroy', name='Reward', line=dict(color='#ab63fa', width=3)))
173
+ fig3.update_layout(title="Step Reward", height=200, margin=dict(l=20, r=20, t=40, b=20), xaxis_title="Step", yaxis_title="Reward (0-1)")
174
+ st.plotly_chart(fig3, use_container_width=True, config={'displayModeBar': False})
175
+
176
+ # Breakdown
177
+ fig4 = go.Figure()
178
+ fig4.add_trace(go.Scatter(x=df['step'], y=df['cost_score'], name='Cost', line=dict(dash='dot')))
179
+ fig4.add_trace(go.Scatter(x=df['step'], y=df['carbon_score'], name='Carbon', line=dict(dash='dash')))
180
+ fig4.add_trace(go.Scatter(x=df['step'], y=df['stability_score'], name='Stability'))
181
+ fig4.update_layout(title="Reward Breakdown", height=220, margin=dict(l=20, r=20, t=40, b=20), legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1))
182
+ st.plotly_chart(fig4, use_container_width=True, config={'displayModeBar': False})
183
+ else:
184
+ st.info("Press 'β–Ά Step' or '⏭ Run Episode' in the sidebar to see performance charts.")
185
+ for _ in range(12): st.empty() # padding to match height
186
 
187
  # Panel 3: Emissions & Training
188
  with col_emissions:
189
+ with st.container(border=True):
190
+ st.subheader("🌍 Emissions & Training")
191
+
192
+ # Carbon Budget Gauge
193
+ max_budget = st.session_state.env.get_task_config(st.session_state.current_task)['carbon_budget']
194
+ current_budget = state.carbon_budget_remaining
195
+
196
+ fig5 = go.Figure(go.Indicator(
197
+ mode = "gauge+number",
198
+ value = current_budget,
199
+ title = {'text': "Carbon Budget (kgCO2)", 'font': {'size': 14}},
200
+ number = {'valueformat': ".0f"},
201
+ gauge = {
202
+ 'axis': {'range': [0, max_budget]},
203
+ 'bar': {'color': "#19d3f3" if current_budget > max_budget * 0.2 else "#ef553b"},
204
+ 'steps': [
205
+ {'range': [0, max_budget * 0.2], 'color': "rgba(239, 85, 59, 0.2)"}
206
+ ]
207
+ }
208
+ ))
209
+ fig5.update_layout(height=200, margin=dict(l=20, r=20, t=40, b=20))
210
+ st.plotly_chart(fig5, use_container_width=True, config={'displayModeBar': False})
211
+
212
+ # RL Training Curve
213
+ st.markdown("**🧠 GRPO Training Progress (Unsloth)**")
214
+ curve_data = load_or_mock_reward_curve()
215
+ df_curve = pd.DataFrame(curve_data)
216
+ fig6 = go.Figure()
217
+ fig6.add_trace(go.Scatter(x=df_curve['step'], y=df_curve['reward'], mode='lines', line=dict(color='#00cc96', width=3)))
218
+ fig6.update_layout(height=180, margin=dict(l=20, r=20, t=10, b=20), xaxis_title="Training Steps", yaxis_title="Avg Reward")
219
+ st.plotly_chart(fig6, use_container_width=True, config={'displayModeBar': False})
220
+
221
+ # Global styling tweaks for clean padding
222
+ st.markdown("""
223
+ <style>
224
+ div[data-testid="stMetric"] {
225
+ background-color: rgba(128, 128, 128, 0.05);
226
+ padding: 10px 15px;
227
+ border-radius: 8px;
228
+ }
229
+ div[data-testid="stDecoration"] {
230
+ display: none;
231
+ }
232
+ </style>
233
+ """, unsafe_allow_html=True)