UCS2014 commited on
Commit
d3b3c33
·
verified ·
1 Parent(s): 8aa4557

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -45
app.py CHANGED
@@ -22,7 +22,9 @@ TARGET = "UCS"
22
  MODELS_DIR = Path("models")
23
  DEFAULT_MODEL = MODELS_DIR / "ucs_rf.joblib"
24
  MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
25
- COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
 
 
26
 
27
  # ---- Plot sizing controls ----
28
  CROSS_W = 450 # px (matplotlib figure size; Streamlit will still scale)
@@ -39,33 +41,41 @@ st.set_page_config(page_title="ST_GeoMech_UCS", page_icon="logo.png", layout="wi
39
  # This is the new CSS block for the sticky header and message box
40
  st.markdown("""
41
  <style>
42
- /* CSS for the main app title in the sidebar and password gate */
43
  .app-title {
44
- color: #89b4f2; /* Light blue color for the title */
45
  font-weight:800;
46
  font-size:1.2rem;
47
  }
48
 
49
- /* CSS to make the header sticky */
50
  .fixed-header-container {
51
  position: sticky;
52
  top: 0;
53
  z-index: 1000;
54
- background-color: #f0f2f6; /* Adjust to match your app's background color */
55
  padding: 10px 0;
56
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
 
 
 
 
 
 
 
 
 
57
  }
58
 
59
- /* CSS to ensure main content doesn't get hidden under the sticky header */
60
  .main .block-container {
61
- padding-top: 250px; /* Adjust this value to match the height of your sticky header */
62
  }
63
 
64
  /* General CSS */
65
  .brand-logo { width: 16px; height: auto; object-fit: contain; }
66
  .sidebar-header { display:flex; align-items:center; gap:12px; }
67
  .sidebar-header .text h1 { font-size: 1.05rem; margin:0; line-height:1.1; }
68
- .sidebar-header .text .tag { font-size: .85rem; color:#6b7280; margin:2px 0 0; }
69
  .centered-container {
70
  display: flex;
71
  flex-direction: column;
@@ -78,18 +88,20 @@ st.markdown("""
78
  # Make the Preview expander title & tabs sticky (pinned to the top)
79
  st.markdown("""
80
  <style>
 
81
  div[data-testid="stExpander"] > details > summary {
82
  position: sticky;
83
  top: 0;
84
  z-index: 10;
85
- background: #fff;
86
- border-bottom: 1px solid #eee;
87
  }
 
88
  div[data-testid="stExpander"] div[data-baseweb="tab-list"] {
89
  position: sticky;
90
- top: 42px; /* adjust if your expander header height differs */
91
  z-index: 9;
92
- background: #fff;
93
  padding-top: 6px;
94
  }
95
  </style>
@@ -129,7 +141,7 @@ def add_password_gate() -> None:
129
  <div class="centered-container">
130
  <img src="{inline_logo('logo.png')}" style="width: 200px; height: auto; object-fit: contain;">
131
  <div class='app-title' style='margin-top: 10px;'>ST_GeoMech_UCS</div>
132
- <div style='color:#FFD700;'>Smart Thinking • Secure Access</div>
133
  </div>
134
  """, unsafe_allow_html=True
135
  )
@@ -201,7 +213,7 @@ def df_centered_rounded(df: pd.DataFrame, hide_index=True):
201
  # =========================
202
  def cross_plot_static(actual, pred):
203
  a = pd.Series(actual, dtype=float)
204
- p = pd.Series(pred, dtype=float)
205
 
206
  fixed_min, fixed_max = 6000, 10000
207
  ticks = np.arange(fixed_min, fixed_max + 1, 1000)
@@ -212,6 +224,9 @@ def cross_plot_static(actual, pred):
212
  dpi=dpi,
213
  constrained_layout=False
214
  )
 
 
 
215
 
216
  ax.scatter(a, p, s=16, c=COLORS["pred"], alpha=0.9, linewidths=0)
217
  ax.plot([fixed_min, fixed_max], [fixed_min, fixed_max],
@@ -219,22 +234,21 @@ def cross_plot_static(actual, pred):
219
 
220
  ax.set_xlim(fixed_min, fixed_max)
221
  ax.set_ylim(fixed_min, fixed_max)
222
- ax.set_xticks(ticks)
223
- ax.set_yticks(ticks)
224
  ax.set_aspect("equal", adjustable="box") # true 45°
225
 
226
  fmt = FuncFormatter(lambda x, _: f"{int(x):,}")
227
  ax.xaxis.set_major_formatter(fmt)
228
  ax.yaxis.set_major_formatter(fmt)
229
 
230
- ax.set_xlabel("Actual UCS (psi)", fontweight="bold", fontsize=12, color="black")
231
- ax.set_ylabel("Predicted UCS (psi)", fontweight="bold", fontsize=12, color="black")
232
- ax.tick_params(labelsize=10, colors="black")
 
233
 
234
  ax.grid(True, linestyle=":", alpha=0.3)
235
  for spine in ax.spines.values():
236
  spine.set_linewidth(1.1)
237
- spine.set_color("#444")
238
 
239
  fig.subplots_adjust(left=0.16, bottom=0.16, right=0.98, top=0.98)
240
  return fig
@@ -279,38 +293,40 @@ def track_plot(df, include_actual=True):
279
 
280
  fig.update_layout(
281
  height=TRACK_H, width=None, # width auto-fits the column
282
- paper_bgcolor="#fff", plot_bgcolor="#fff",
 
283
  margin=dict(l=64, r=16, t=36, b=48), hovermode="closest",
284
- font=dict(size=FONT_SZ, color="#000"),
 
285
  legend=dict(
286
  x=0.98, y=0.05, xanchor="right", yanchor="bottom",
287
- bgcolor="rgba(255,255,255,0.75)", bordercolor="#ccc", borderwidth=1
288
  ),
289
  legend_title_text=""
290
  )
291
 
292
- # Bold, black axis titles & ticks
293
  fig.update_xaxes(
294
  title_text="UCS (psi)",
295
- title_font=dict(size=16, family=BOLD_FONT, color="#000"),
296
- tickfont=dict(size=11, family=BOLD_FONT, color="#000"),
297
  side="top",
298
  range=[xmin, xmax],
299
  ticks="outside",
300
  tickformat=",.0f",
301
  tickmode="auto",
302
  tick0=tick0,
303
- showline=True, linewidth=1.2, linecolor="#444", mirror=True,
304
- showgrid=True, gridcolor="rgba(0,0,0,0.12)", automargin=True
305
  )
306
  fig.update_yaxes(
307
  title_text=ylab,
308
- title_font=dict(size=16, family=BOLD_FONT, color="#000"),
309
- tickfont=dict(size=11, family=BOLD_FONT, color="#000"),
310
  range=y_range,
311
  ticks="outside",
312
- showline=True, linewidth=1.2, linecolor="#444", mirror=True,
313
- showgrid=True, gridcolor="rgba(0,0,0,0.12)", automargin=True
314
  )
315
 
316
  return fig
@@ -321,17 +337,22 @@ def preview_tracks(df: pd.DataFrame, cols: list[str]):
321
  n = len(cols)
322
  if n == 0:
323
  fig, ax = plt.subplots(figsize=(4, 2))
324
- ax.text(0.5,0.5,"No selected columns",ha="center",va="center"); ax.axis("off")
325
  return fig
326
  fig, axes = plt.subplots(1, n, figsize=(2.2*n, 7.0), sharey=True, dpi=100)
 
327
  if n == 1: axes = [axes]
328
  idx = np.arange(1, len(df) + 1)
329
  for ax, col in zip(axes, cols):
330
- ax.plot(df[col], idx, '-', lw=1.4, color="#333")
331
- ax.set_xlabel(col); ax.xaxis.set_label_position('top'); ax.xaxis.tick_top(); ax.invert_yaxis()
 
 
332
  ax.grid(True, linestyle=":", alpha=0.3)
333
- for s in ax.spines.values(): s.set_visible(True)
334
- axes[0].set_ylabel("Point Index")
 
 
335
  return fig
336
 
337
  # Modal wrapper (Streamlit compatibility)
@@ -420,7 +441,7 @@ st.sidebar.markdown(f"""
420
  <div class="centered-container">
421
  <img src="{inline_logo('logo.png')}" style="width: 200px; height: auto; object-fit: contain;">
422
  <div class='app-title'>ST_GeoMech_UCS</div>
423
- <div style='color:#667085;'>Real-Time UCS Tracking While Drilling</div>
424
  </div>
425
  """, unsafe_allow_html=True
426
  )
@@ -658,11 +679,11 @@ if st.session_state.app_step == "predict":
658
  table = pd.DataFrame({
659
  "Metric": ["# points","Pred min","Pred max","Pred mean","Pred std","OOR %"],
660
  "Value": [sv["n"],
661
- round(sv["pred_min"],2),
662
- round(sv["pred_max"],2),
663
- round(sv["pred_mean"],2),
664
- round(sv["pred_std"],2),
665
- f'{sv["oor"]:.1f}%']
666
  })
667
  st.success("Predictions ready ✓")
668
  df_centered_rounded(table, hide_index=True)
@@ -679,7 +700,7 @@ if st.session_state.app_step == "predict":
679
  st.markdown("---")
680
  st.markdown(
681
  """
682
- <div style='text-align:center; color:#6b7280; line-height:1.6'>
683
  ST_GeoMech_UCS • © Smart Thinking<br/>
684
  <strong>Visit our website:</strong> <a href='https://www.smartthinking.com.sa' target='_blank'>smartthinking.com.sa</a>
685
  </div>
 
22
  MODELS_DIR = Path("models")
23
  DEFAULT_MODEL = MODELS_DIR / "ucs_rf.joblib"
24
  MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
25
+
26
+ # Updated colors for a dark blue theme
27
+ COLORS = {"pred": "#4A90E2", "actual": "#FFC107", "ref": "#B0B0B0"}
28
 
29
  # ---- Plot sizing controls ----
30
  CROSS_W = 450 # px (matplotlib figure size; Streamlit will still scale)
 
41
  # This is the new CSS block for the sticky header and message box
42
  st.markdown("""
43
  <style>
44
+ /* Changed to a lighter blue for visibility on a dark background */
45
  .app-title {
46
+ color: #89b4f2;
47
  font-weight:800;
48
  font-size:1.2rem;
49
  }
50
 
51
+ /* Changed background to a dark blue to match the theme */
52
  .fixed-header-container {
53
  position: sticky;
54
  top: 0;
55
  z-index: 1000;
56
+ background-color: #0a192f;
57
  padding: 10px 0;
58
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
59
+ }
60
+
61
+ /* Changed to a light gray/blue to be visible on the dark background */
62
+ .info-box {
63
+ background-color: #172a45;
64
+ color: #b1c7e0;
65
+ padding: 10px;
66
+ border-radius: 5px;
67
+ margin-bottom: 1rem;
68
  }
69
 
 
70
  .main .block-container {
71
+ padding-top: 250px;
72
  }
73
 
74
  /* General CSS */
75
  .brand-logo { width: 16px; height: auto; object-fit: contain; }
76
  .sidebar-header { display:flex; align-items:center; gap:12px; }
77
  .sidebar-header .text h1 { font-size: 1.05rem; margin:0; line-height:1.1; }
78
+ .sidebar-header .text .tag { font-size: .85rem; color:#b1c7e0; margin:2px 0 0; } /* Changed color */
79
  .centered-container {
80
  display: flex;
81
  flex-direction: column;
 
88
  # Make the Preview expander title & tabs sticky (pinned to the top)
89
  st.markdown("""
90
  <style>
91
+ /* Updated to a dark background for consistency */
92
  div[data-testid="stExpander"] > details > summary {
93
  position: sticky;
94
  top: 0;
95
  z-index: 10;
96
+ background: #0a192f;
97
+ border-bottom: 1px solid #172a45;
98
  }
99
+ /* Updated to a dark background for consistency */
100
  div[data-testid="stExpander"] div[data-baseweb="tab-list"] {
101
  position: sticky;
102
+ top: 42px;
103
  z-index: 9;
104
+ background: #0a192f;
105
  padding-top: 6px;
106
  }
107
  </style>
 
141
  <div class="centered-container">
142
  <img src="{inline_logo('logo.png')}" style="width: 200px; height: auto; object-fit: contain;">
143
  <div class='app-title' style='margin-top: 10px;'>ST_GeoMech_UCS</div>
144
+ <div style='color:#b1c7e0;'>Smart Thinking • Secure Access</div>
145
  </div>
146
  """, unsafe_allow_html=True
147
  )
 
213
  # =========================
214
  def cross_plot_static(actual, pred):
215
  a = pd.Series(actual, dtype=float)
216
+ p = pd.Series(pred, dtype=float)
217
 
218
  fixed_min, fixed_max = 6000, 10000
219
  ticks = np.arange(fixed_min, fixed_max + 1, 1000)
 
224
  dpi=dpi,
225
  constrained_layout=False
226
  )
227
+ # Set the background color of the plot
228
+ fig.patch.set_facecolor('#0a192f')
229
+ ax.set_facecolor('#0a192f')
230
 
231
  ax.scatter(a, p, s=16, c=COLORS["pred"], alpha=0.9, linewidths=0)
232
  ax.plot([fixed_min, fixed_max], [fixed_min, fixed_max],
 
234
 
235
  ax.set_xlim(fixed_min, fixed_max)
236
  ax.set_ylim(fixed_min, fixed_max)
 
 
237
  ax.set_aspect("equal", adjustable="box") # true 45°
238
 
239
  fmt = FuncFormatter(lambda x, _: f"{int(x):,}")
240
  ax.xaxis.set_major_formatter(fmt)
241
  ax.yaxis.set_major_formatter(fmt)
242
 
243
+ # Changed text and tick colors to a light blue for contrast
244
+ ax.set_xlabel("Actual UCS (psi)", fontweight="bold", fontsize=12, color="#E0E7FF")
245
+ ax.set_ylabel("Predicted UCS (psi)", fontweight="bold", fontsize=12, color="#E0E7FF")
246
+ ax.tick_params(labelsize=10, colors="#E0E7FF")
247
 
248
  ax.grid(True, linestyle=":", alpha=0.3)
249
  for spine in ax.spines.values():
250
  spine.set_linewidth(1.1)
251
+ spine.set_color("#A0A0A0") # Changed spine color to a lighter gray
252
 
253
  fig.subplots_adjust(left=0.16, bottom=0.16, right=0.98, top=0.98)
254
  return fig
 
293
 
294
  fig.update_layout(
295
  height=TRACK_H, width=None, # width auto-fits the column
296
+ # Updated background colors for dark theme
297
+ paper_bgcolor="#0a192f", plot_bgcolor="#0a192f",
298
  margin=dict(l=64, r=16, t=36, b=48), hovermode="closest",
299
+ # Updated font color
300
+ font=dict(size=FONT_SZ, color="#E0E7FF"),
301
  legend=dict(
302
  x=0.98, y=0.05, xanchor="right", yanchor="bottom",
303
+ bgcolor="rgba(10,25,47,0.75)", bordercolor="#ccc", borderwidth=1
304
  ),
305
  legend_title_text=""
306
  )
307
 
308
+ # Bold, light blue axis titles & ticks
309
  fig.update_xaxes(
310
  title_text="UCS (psi)",
311
+ title_font=dict(size=16, family=BOLD_FONT, color="#E0E7FF"),
312
+ tickfont=dict(size=11, family=BOLD_FONT, color="#E0E7FF"),
313
  side="top",
314
  range=[xmin, xmax],
315
  ticks="outside",
316
  tickformat=",.0f",
317
  tickmode="auto",
318
  tick0=tick0,
319
+ showline=True, linewidth=1.2, linecolor="#A0A0A0", mirror=True,
320
+ showgrid=True, gridcolor="rgba(255,255,255,0.12)", automargin=True
321
  )
322
  fig.update_yaxes(
323
  title_text=ylab,
324
+ title_font=dict(size=16, family=BOLD_FONT, color="#E0E7FF"),
325
+ tickfont=dict(size=11, family=BOLD_FONT, color="#E0E7FF"),
326
  range=y_range,
327
  ticks="outside",
328
+ showline=True, linewidth=1.2, linecolor="#A0A0A0", mirror=True,
329
+ showgrid=True, gridcolor="rgba(255,255,255,0.12)", automargin=True
330
  )
331
 
332
  return fig
 
337
  n = len(cols)
338
  if n == 0:
339
  fig, ax = plt.subplots(figsize=(4, 2))
340
+ ax.text(0.5,0.5,"No selected columns",ha="center",va="center", color="#E0E7FF"); ax.axis("off")
341
  return fig
342
  fig, axes = plt.subplots(1, n, figsize=(2.2*n, 7.0), sharey=True, dpi=100)
343
+ fig.patch.set_facecolor('#0a192f')
344
  if n == 1: axes = [axes]
345
  idx = np.arange(1, len(df) + 1)
346
  for ax, col in zip(axes, cols):
347
+ ax.set_facecolor('#0a192f')
348
+ ax.plot(df[col], idx, '-', lw=1.4, color="#b1c7e0") # Light blue plot line
349
+ ax.set_xlabel(col, color="#b1c7e0"); ax.xaxis.set_label_position('top'); ax.xaxis.tick_top(); ax.invert_yaxis() # Light blue labels
350
+ ax.tick_params(axis='both', colors='#b1c7e0') # Light blue ticks
351
  ax.grid(True, linestyle=":", alpha=0.3)
352
+ for s in ax.spines.values():
353
+ s.set_visible(True)
354
+ s.set_edgecolor("#A0A0A0") # Lighter spine color
355
+ axes[0].set_ylabel("Point Index", color="#b1c7e0") # Light blue label
356
  return fig
357
 
358
  # Modal wrapper (Streamlit compatibility)
 
441
  <div class="centered-container">
442
  <img src="{inline_logo('logo.png')}" style="width: 200px; height: auto; object-fit: contain;">
443
  <div class='app-title'>ST_GeoMech_UCS</div>
444
+ <div style='color:#b1c7e0;'>Real-Time UCS Tracking While Drilling</div>
445
  </div>
446
  """, unsafe_allow_html=True
447
  )
 
679
  table = pd.DataFrame({
680
  "Metric": ["# points","Pred min","Pred max","Pred mean","Pred std","OOR %"],
681
  "Value": [sv["n"],
682
+ round(sv["pred_min"],2),
683
+ round(sv["pred_max"],2),
684
+ round(sv["pred_mean"],2),
685
+ round(sv["pred_std"],2),
686
+ f'{sv["oor"]:.1f}%']
687
  })
688
  st.success("Predictions ready ✓")
689
  df_centered_rounded(table, hide_index=True)
 
700
  st.markdown("---")
701
  st.markdown(
702
  """
703
+ <div style='text-align:center; color:#b1c7e0; line-height:1.6'>
704
  ST_GeoMech_UCS • © Smart Thinking<br/>
705
  <strong>Visit our website:</strong> <a href='https://www.smartthinking.com.sa' target='_blank'>smartthinking.com.sa</a>
706
  </div>