Spaces:
Sleeping
Sleeping
[FIX] tab4: fix heatmap zero-display for tiny values, remove unused imports and redundant session state inits
Browse files- tabs/tab4_optimization.py +30 -14
tabs/tab4_optimization.py
CHANGED
|
@@ -2,11 +2,9 @@ from collections import defaultdict
|
|
| 2 |
import datetime
|
| 3 |
import io
|
| 4 |
import json
|
| 5 |
-
import re
|
| 6 |
import unicodedata
|
| 7 |
import zipfile
|
| 8 |
import openpyxl
|
| 9 |
-
import numpy as np
|
| 10 |
import pandas as pd
|
| 11 |
import streamlit as st
|
| 12 |
import plotly.express as px
|
|
@@ -317,9 +315,10 @@ def panel_load_from_json_or_csv():
|
|
| 317 |
# Restore custom resource batches if present in the scenario
|
| 318 |
st.session_state.custom_resources = data.get("custom_resources", [])
|
| 319 |
st.session_state.enabled_methods = data.get("enabled_methods", {})
|
| 320 |
-
# Reset auto_disabled_methods so
|
| 321 |
-
# clean slate matching the loaded scenario (avoids
|
| 322 |
-
# would prevent or incorrectly trigger re-enable on
|
|
|
|
| 323 |
st.session_state.auto_disabled_methods = set()
|
| 324 |
clear_widget_keys()
|
| 325 |
for _m, _c in st.session_state.constraints.items():
|
|
@@ -684,14 +683,33 @@ def show_heatmap(df_result, resource_caps, method_costs, custom_resources=None,
|
|
| 684 |
df_heat = pd.DataFrame(matrix_pct, index=y_labels, columns=available)
|
| 685 |
df_exact = pd.DataFrame(matrix_exact, index=y_labels, columns=available)
|
| 686 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 687 |
fig = px.imshow(
|
| 688 |
-
df_heat, color_continuous_scale=PLOTLY_HEATMAP_SCALE,
|
| 689 |
labels=dict(x="Resource", y="Method", color="% Used"),
|
| 690 |
)
|
| 691 |
matrix_exact_fmt = [[f"{v:.10g}" for v in row] for row in matrix_exact]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 692 |
fig.update_traces(
|
| 693 |
-
|
| 694 |
-
|
|
|
|
| 695 |
)
|
| 696 |
n_rows = len(df_heat.index)
|
| 697 |
n_cols = len(df_heat.columns)
|
|
@@ -721,7 +739,7 @@ def show_heatmap(df_result, resource_caps, method_costs, custom_resources=None,
|
|
| 721 |
df_pct_display = df_export_pct.copy()
|
| 722 |
for col in df_pct_display.columns:
|
| 723 |
if col != "Method":
|
| 724 |
-
df_pct_display[col] = df_pct_display[col].map(lambda x: f"{x
|
| 725 |
st.dataframe(df_pct_display, width='stretch', hide_index=True)
|
| 726 |
|
| 727 |
register_chart_data("Resource usage heatmap (% of cap)", df_export_pct)
|
|
@@ -811,7 +829,6 @@ def show_resource_balance(latest):
|
|
| 811 |
st.markdown('<p class="crra-sub-heading">Resource balance: used vs available</p>', unsafe_allow_html=True)
|
| 812 |
resource_caps = latest["resource_caps"]
|
| 813 |
used_total = latest["resource_used_total"]
|
| 814 |
-
remaining = latest["resource_remaining"]
|
| 815 |
|
| 816 |
resource_to_group = get_resource_to_group()
|
| 817 |
# Custom batch names: their amounts come from resource_caps (expanded batches
|
|
@@ -1352,15 +1369,14 @@ def render_tab():
|
|
| 1352 |
unsafe_allow_html=True
|
| 1353 |
)
|
| 1354 |
|
|
|
|
|
|
|
|
|
|
| 1355 |
for key, default in [
|
| 1356 |
-
("resource_caps", {}), ("constraints", {}),
|
| 1357 |
-
("costs", {}), ("scenarios", {}),
|
| 1358 |
("excel_uploader_key", 0),
|
| 1359 |
("scenario_uploader_key", 0)
|
| 1360 |
]:
|
| 1361 |
st.session_state.setdefault(key, default)
|
| 1362 |
-
if "enabled_methods" not in st.session_state:
|
| 1363 |
-
st.session_state.enabled_methods = {}
|
| 1364 |
|
| 1365 |
tab_run, tab_results, tab_resources, tab_bottleneck, tab_export, tab_reset = st.tabs([
|
| 1366 |
"▶️ Run",
|
|
|
|
| 2 |
import datetime
|
| 3 |
import io
|
| 4 |
import json
|
|
|
|
| 5 |
import unicodedata
|
| 6 |
import zipfile
|
| 7 |
import openpyxl
|
|
|
|
| 8 |
import pandas as pd
|
| 9 |
import streamlit as st
|
| 10 |
import plotly.express as px
|
|
|
|
| 315 |
# Restore custom resource batches if present in the scenario
|
| 316 |
st.session_state.custom_resources = data.get("custom_resources", [])
|
| 317 |
st.session_state.enabled_methods = data.get("enabled_methods", {})
|
| 318 |
+
# Reset auto_disabled_methods so refresh_active_methods (app.py's shared
|
| 319 |
+
# init) starts from a clean slate matching the loaded scenario (avoids
|
| 320 |
+
# stale entries that would prevent or incorrectly trigger re-enable on
|
| 321 |
+
# the next render).
|
| 322 |
st.session_state.auto_disabled_methods = set()
|
| 323 |
clear_widget_keys()
|
| 324 |
for _m, _c in st.session_state.constraints.items():
|
|
|
|
| 683 |
df_heat = pd.DataFrame(matrix_pct, index=y_labels, columns=available)
|
| 684 |
df_exact = pd.DataFrame(matrix_exact, index=y_labels, columns=available)
|
| 685 |
|
| 686 |
+
# A genuine but tiny usage (e.g. 0.03%) rounds to "0.0" at 1 decimal,
|
| 687 |
+
# visually indistinguishable from a true zero. Below 0.05 show the exact
|
| 688 |
+
# value instead (enough decimals to reveal it, trailing zeros stripped)
|
| 689 |
+
# so a real (if small) contribution never looks like "not used at all".
|
| 690 |
+
def _fmt_pct(v):
|
| 691 |
+
if v <= 0:
|
| 692 |
+
return "0"
|
| 693 |
+
if v < 0.1:
|
| 694 |
+
s = f"{v:.4f}".rstrip("0").rstrip(".")
|
| 695 |
+
return s if s else "0"
|
| 696 |
+
return f"{v:.1f}"
|
| 697 |
+
|
| 698 |
+
text_matrix = [[_fmt_pct(v) for v in row] for row in matrix_pct]
|
| 699 |
+
|
| 700 |
fig = px.imshow(
|
| 701 |
+
df_heat, color_continuous_scale=PLOTLY_HEATMAP_SCALE,
|
| 702 |
labels=dict(x="Resource", y="Method", color="% Used"),
|
| 703 |
)
|
| 704 |
matrix_exact_fmt = [[f"{v:.10g}" for v in row] for row in matrix_exact]
|
| 705 |
+
pct_and_exact = [
|
| 706 |
+
[[text_matrix[i][j], matrix_exact_fmt[i][j]] for j in range(len(available))]
|
| 707 |
+
for i in range(len(y_labels))
|
| 708 |
+
]
|
| 709 |
fig.update_traces(
|
| 710 |
+
text=text_matrix, texttemplate="%{text}",
|
| 711 |
+
customdata=pct_and_exact,
|
| 712 |
+
hovertemplate="<b>%{y}</b><br>%{x}<br>% of cap: %{customdata[0]}%<br>Exact: %{customdata[1]}<extra></extra>",
|
| 713 |
)
|
| 714 |
n_rows = len(df_heat.index)
|
| 715 |
n_cols = len(df_heat.columns)
|
|
|
|
| 739 |
df_pct_display = df_export_pct.copy()
|
| 740 |
for col in df_pct_display.columns:
|
| 741 |
if col != "Method":
|
| 742 |
+
df_pct_display[col] = df_pct_display[col].map(lambda x: f"{_fmt_pct(x)}%")
|
| 743 |
st.dataframe(df_pct_display, width='stretch', hide_index=True)
|
| 744 |
|
| 745 |
register_chart_data("Resource usage heatmap (% of cap)", df_export_pct)
|
|
|
|
| 829 |
st.markdown('<p class="crra-sub-heading">Resource balance: used vs available</p>', unsafe_allow_html=True)
|
| 830 |
resource_caps = latest["resource_caps"]
|
| 831 |
used_total = latest["resource_used_total"]
|
|
|
|
| 832 |
|
| 833 |
resource_to_group = get_resource_to_group()
|
| 834 |
# Custom batch names: their amounts come from resource_caps (expanded batches
|
|
|
|
| 1369 |
unsafe_allow_html=True
|
| 1370 |
)
|
| 1371 |
|
| 1372 |
+
# resource_caps / constraints / costs / scenarios / enabled_methods are
|
| 1373 |
+
# already guaranteed by app.py's shared init (runs before any tab renders)
|
| 1374 |
+
# — only these two upload-widget counters are tab4-specific.
|
| 1375 |
for key, default in [
|
|
|
|
|
|
|
| 1376 |
("excel_uploader_key", 0),
|
| 1377 |
("scenario_uploader_key", 0)
|
| 1378 |
]:
|
| 1379 |
st.session_state.setdefault(key, default)
|
|
|
|
|
|
|
| 1380 |
|
| 1381 |
tab_run, tab_results, tab_resources, tab_bottleneck, tab_export, tab_reset = st.tabs([
|
| 1382 |
"▶️ Run",
|