UCS2014 commited on
Commit
ef1eb9f
·
verified ·
1 Parent(s): 2308c33

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -49
app.py CHANGED
@@ -29,15 +29,15 @@ from sklearn.impute import SimpleImputer
29
  APP_NAME = "ST_Min_Horizontal_Stress"
30
  TAGLINE = "Real-Time Minimum Horizontal Stress Prediction"
31
 
32
- # -------- Option B (canonical names = what your files already have) --------
33
  FEATURES = ["Q (gpm)", "SPP (psi)", "T (kft.lbf)", "WOB (klbf)", "ROP (ft/h)"]
34
  TARGET = "MINStress_Actual"
35
  PRED_COL = "MINStress_Pred"
36
  ACTUAL_COL = TARGET
37
  TRANSFORM = "none" # "none" | "log10" | "ln"
38
- UNITS = "MPa"
39
 
40
- # ---- "Best" (fixed) model setup baked into the code (no grid search UI) ----
41
  BEST_PARAMS = dict(
42
  n_estimators=400,
43
  max_depth=None,
@@ -354,7 +354,7 @@ def cross_plot_static(actual, pred):
354
  ax.set_xticks(ticks); ax.set_yticks(ticks)
355
  ax.set_aspect("equal", adjustable="box")
356
 
357
- fmt = FuncFormatter(lambda x, _: f"{x:.2f}")
358
  ax.xaxis.set_major_formatter(fmt); ax.yaxis.set_major_formatter(fmt)
359
 
360
  ax.set_xlabel(f"Actual Min Stress ({UNITS})", fontweight="bold", fontsize=10, color="black")
@@ -415,7 +415,9 @@ def track_plot(df, include_actual=True):
415
  title_font=dict(size=20, family=BOLD_FONT, color="#000"),
416
  tickfont=dict(size=15, family=BOLD_FONT, color="#000"),
417
  side="top", range=[xmin, xmax],
418
- ticks="outside", tickformat=",.2f", tickmode="auto", tick0=tick0,
 
 
419
  showline=True, linewidth=1.2, linecolor="#444", mirror=True,
420
  showgrid=True, gridcolor="rgba(0,0,0,0.12)", automargin=True
421
  )
@@ -496,8 +498,11 @@ st.session_state.setdefault("dev_file_name","")
496
  st.session_state.setdefault("dev_file_bytes",b"")
497
  st.session_state.setdefault("dev_file_loaded",False)
498
  st.session_state.setdefault("dev_preview",False)
499
- st.session_state.setdefault("show_preview_modal", False)
500
- st.session_state.setdefault("fitted_model", None) # cache trained pipeline
 
 
 
501
 
502
  # =========================
503
  # Sidebar branding
@@ -527,6 +532,50 @@ def sticky_header(title, message):
527
  unsafe_allow_html=True
528
  )
529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
530
  # =========================
531
  # INTRO
532
  # =========================
@@ -567,21 +616,26 @@ if st.session_state.app_step == "dev":
567
  df0 = next(iter(tmp.values()))
568
  st.sidebar.caption(f"**Data loaded:** {st.session_state.dev_file_name} • {df0.shape[0]} rows × {df0.shape[1]} cols")
569
 
 
570
  if st.sidebar.button("Preview data", use_container_width=True, disabled=not st.session_state.dev_file_loaded):
571
- st.session_state.show_preview_modal = True
572
- st.session_state.dev_preview = True
 
573
 
574
  run = st.sidebar.button("Run Model", type="primary", use_container_width=True)
575
  if st.sidebar.button("Proceed to Validation ▶", use_container_width=True): st.session_state.app_step="validate"; st.rerun()
576
  if st.sidebar.button("Proceed to Prediction ▶", use_container_width=True): st.session_state.app_step="predict"; st.rerun()
577
 
578
- if st.session_state.dev_file_loaded and st.session_state.dev_preview:
579
  sticky_header("Case Building", "Previewed ✓ — now click **Run Model**.")
580
  elif st.session_state.dev_file_loaded:
581
  sticky_header("Case Building", "📄 **Preview uploaded data** using the sidebar button, then click **Run Model**.")
582
  else:
583
  sticky_header("Case Building", "**Upload your data to build a case, then run the model to review performance.**")
584
 
 
 
 
585
  if run and st.session_state.dev_file_bytes:
586
  book = read_book_bytes(st.session_state.dev_file_bytes)
587
  sh_train = _find_sheet(book, ["Train","Training","training2","train","training"])
@@ -674,13 +728,19 @@ if st.session_state.app_step == "validate":
674
  if book:
675
  df0 = next(iter(book.values()))
676
  st.sidebar.caption(f"**Data loaded:** {up.name} • {df0.shape[0]} rows × {df0.shape[1]} cols")
 
 
677
  if st.sidebar.button("Preview data", use_container_width=True, disabled=(up is None)):
678
- st.session_state.show_preview_modal = True
 
 
 
679
  go_btn = st.sidebar.button("Predict & Validate", type="primary", use_container_width=True)
680
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
681
  if st.sidebar.button("Proceed to Prediction ▶", use_container_width=True): st.session_state.app_step="predict"; st.rerun()
682
 
683
  sticky_header("Validate the Model", "Upload a dataset with the same **features** and **MINStress_Actual** to evaluate performance.")
 
684
 
685
  if go_btn and up is not None:
686
  if st.session_state.fitted_model is None:
@@ -759,12 +819,18 @@ if st.session_state.app_step == "predict":
759
  if book:
760
  df0 = next(iter(book.values()))
761
  st.sidebar.caption(f"**Data loaded:** {up.name} • {df0.shape[0]} rows × {df0.shape[1]} cols")
 
 
762
  if st.sidebar.button("Preview data", use_container_width=True, disabled=(up is None)):
763
- st.session_state.show_preview_modal = True
 
 
 
764
  go_btn = st.sidebar.button("Predict", type="primary", use_container_width=True)
765
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
766
 
767
  sticky_header("Prediction", "Upload a dataset with the 5 feature columns (no actual column).")
 
768
 
769
  if go_btn and up is not None:
770
  if st.session_state.fitted_model is None:
@@ -809,43 +875,6 @@ if st.session_state.app_step == "predict":
809
  use_container_width=False, config={"displayModeBar": False, "scrollZoom": True})
810
  render_export_button(phase_key="predict")
811
 
812
- # =========================
813
- # Preview modal
814
- # =========================
815
- if st.session_state.show_preview_modal:
816
- book_to_preview = {}
817
- if st.session_state.app_step == "dev":
818
- book_to_preview = read_book_bytes(st.session_state.dev_file_bytes)
819
- elif st.session_state.app_step in ["validate", "predict"] and 'up' in locals() and up is not None:
820
- book_to_preview = read_book_bytes(up.getvalue())
821
-
822
- with st.expander("Preview data", expanded=True):
823
- if not book_to_preview:
824
- st.markdown('<div class="st-message-box">No data loaded yet.</div>', unsafe_allow_html=True)
825
- else:
826
- names = list(book_to_preview.keys())
827
- tabs = st.tabs(names)
828
- for t, name in zip(tabs, names):
829
- with t:
830
- df = book_to_preview[name]
831
- t1, t2 = st.tabs(["Tracks", "Summary"])
832
- with t1:
833
- st.pyplot(preview_tracks(df, FEATURES), use_container_width=True)
834
- with t2:
835
- feat_present = [c for c in FEATURES if c in df.columns]
836
- if not feat_present:
837
- st.info("No feature columns found to summarize.")
838
- else:
839
- tbl = (
840
- df[feat_present]
841
- .agg(['min','max','mean','std'])
842
- .T.rename(columns={"min":"Min","max":"Max","mean":"Mean","std":"Std"})
843
- .reset_index(names="Feature")
844
- )
845
- df_centered_rounded(tbl)
846
-
847
- st.session_state.show_preview_modal = False
848
-
849
  # =========================
850
  # Footer
851
  # =========================
 
29
  APP_NAME = "ST_Min_Horizontal_Stress"
30
  TAGLINE = "Real-Time Minimum Horizontal Stress Prediction"
31
 
32
+ # -------- Canonical names (match your files) --------
33
  FEATURES = ["Q (gpm)", "SPP (psi)", "T (kft.lbf)", "WOB (klbf)", "ROP (ft/h)"]
34
  TARGET = "MINStress_Actual"
35
  PRED_COL = "MINStress_Pred"
36
  ACTUAL_COL = TARGET
37
  TRANSFORM = "none" # "none" | "log10" | "ln"
38
+ UNITS = "Psi"
39
 
40
+ # ---- Fixed ("best") model params baked into the code ----
41
  BEST_PARAMS = dict(
42
  n_estimators=400,
43
  max_depth=None,
 
354
  ax.set_xticks(ticks); ax.set_yticks(ticks)
355
  ax.set_aspect("equal", adjustable="box")
356
 
357
+ fmt = FuncFormatter(lambda x, _: f"{x:.0f}") # no decimals on cross-plot
358
  ax.xaxis.set_major_formatter(fmt); ax.yaxis.set_major_formatter(fmt)
359
 
360
  ax.set_xlabel(f"Actual Min Stress ({UNITS})", fontweight="bold", fontsize=10, color="black")
 
415
  title_font=dict(size=20, family=BOLD_FONT, color="#000"),
416
  tickfont=dict(size=15, family=BOLD_FONT, color="#000"),
417
  side="top", range=[xmin, xmax],
418
+ ticks="outside",
419
+ tickformat=",.0f", # <— no decimals on ticks
420
+ tickmode="auto", tick0=tick0,
421
  showline=True, linewidth=1.2, linecolor="#444", mirror=True,
422
  showgrid=True, gridcolor="rgba(0,0,0,0.12)", automargin=True
423
  )
 
498
  st.session_state.setdefault("dev_file_bytes",b"")
499
  st.session_state.setdefault("dev_file_loaded",False)
500
  st.session_state.setdefault("dev_preview",False)
501
+ st.session_state.setdefault("fitted_model", None) # cache trained pipeline
502
+
503
+ # NEW: persistent top-of-page preview panel state
504
+ st.session_state.setdefault("show_preview_panel", False)
505
+ st.session_state.setdefault("preview_book", {}) # parsed Excel sheets to preview
506
 
507
  # =========================
508
  # Sidebar branding
 
532
  unsafe_allow_html=True
533
  )
534
 
535
+ # ---------- Top-of-page Preview Panel ----------
536
+ def render_preview_panel():
537
+ """If enabled, draws a preview panel at the very top of the page."""
538
+ if not st.session_state.get("show_preview_panel"):
539
+ return
540
+
541
+ st.markdown("## 🔎 Data preview")
542
+ book = st.session_state.get("preview_book", {}) or {}
543
+ if not book:
544
+ st.info("No data loaded yet.")
545
+ col = st.columns(2)[1]
546
+ with col:
547
+ if st.button("Hide preview"):
548
+ st.session_state.show_preview_panel = False
549
+ st.session_state.preview_book = {}
550
+ st.rerun()
551
+ return
552
+
553
+ names = list(book.keys())
554
+ tabs = st.tabs(names + ["✖ Hide preview"])
555
+ for i, name in enumerate(names):
556
+ with tabs[i]:
557
+ df = book[name]
558
+ t1, t2 = st.tabs(["Tracks", "Summary"])
559
+ with t1:
560
+ st.pyplot(preview_tracks(df, FEATURES), use_container_width=True)
561
+ with t2:
562
+ feat_present = [c for c in FEATURES if c in df.columns]
563
+ if not feat_present:
564
+ st.info("No feature columns found to summarize.")
565
+ else:
566
+ tbl = (
567
+ df[feat_present]
568
+ .agg(['min','max','mean','std'])
569
+ .T.rename(columns={"min":"Min","max":"Max","mean":"Mean","std":"Std"})
570
+ .reset_index(names="Feature")
571
+ )
572
+ df_centered_rounded(tbl)
573
+ with tabs[-1]:
574
+ if st.button("Hide preview", use_container_width=True):
575
+ st.session_state.show_preview_panel = False
576
+ st.session_state.preview_book = {}
577
+ st.rerun()
578
+
579
  # =========================
580
  # INTRO
581
  # =========================
 
616
  df0 = next(iter(tmp.values()))
617
  st.sidebar.caption(f"**Data loaded:** {st.session_state.dev_file_name} • {df0.shape[0]} rows × {df0.shape[1]} cols")
618
 
619
+ # PREVIEW button -> show preview panel at top
620
  if st.sidebar.button("Preview data", use_container_width=True, disabled=not st.session_state.dev_file_loaded):
621
+ st.session_state.preview_book = read_book_bytes(st.session_state.dev_file_bytes) if st.session_state.dev_file_bytes else {}
622
+ st.session_state.show_preview_panel = True
623
+ st.rerun()
624
 
625
  run = st.sidebar.button("Run Model", type="primary", use_container_width=True)
626
  if st.sidebar.button("Proceed to Validation ▶", use_container_width=True): st.session_state.app_step="validate"; st.rerun()
627
  if st.sidebar.button("Proceed to Prediction ▶", use_container_width=True): st.session_state.app_step="predict"; st.rerun()
628
 
629
+ if st.session_state.dev_file_loaded and st.session_state.show_preview_panel:
630
  sticky_header("Case Building", "Previewed ✓ — now click **Run Model**.")
631
  elif st.session_state.dev_file_loaded:
632
  sticky_header("Case Building", "📄 **Preview uploaded data** using the sidebar button, then click **Run Model**.")
633
  else:
634
  sticky_header("Case Building", "**Upload your data to build a case, then run the model to review performance.**")
635
 
636
+ # Render the preview panel at the very top (above results)
637
+ render_preview_panel()
638
+
639
  if run and st.session_state.dev_file_bytes:
640
  book = read_book_bytes(st.session_state.dev_file_bytes)
641
  sh_train = _find_sheet(book, ["Train","Training","training2","train","training"])
 
728
  if book:
729
  df0 = next(iter(book.values()))
730
  st.sidebar.caption(f"**Data loaded:** {up.name} • {df0.shape[0]} rows × {df0.shape[1]} cols")
731
+
732
+ # PREVIEW button -> show preview panel at top
733
  if st.sidebar.button("Preview data", use_container_width=True, disabled=(up is None)):
734
+ st.session_state.preview_book = read_book_bytes(up.getvalue()) if up is not None else {}
735
+ st.session_state.show_preview_panel = True
736
+ st.rerun()
737
+
738
  go_btn = st.sidebar.button("Predict & Validate", type="primary", use_container_width=True)
739
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
740
  if st.sidebar.button("Proceed to Prediction ▶", use_container_width=True): st.session_state.app_step="predict"; st.rerun()
741
 
742
  sticky_header("Validate the Model", "Upload a dataset with the same **features** and **MINStress_Actual** to evaluate performance.")
743
+ render_preview_panel() # top-of-page preview
744
 
745
  if go_btn and up is not None:
746
  if st.session_state.fitted_model is None:
 
819
  if book:
820
  df0 = next(iter(book.values()))
821
  st.sidebar.caption(f"**Data loaded:** {up.name} • {df0.shape[0]} rows × {df0.shape[1]} cols")
822
+
823
+ # PREVIEW button -> show preview panel at top
824
  if st.sidebar.button("Preview data", use_container_width=True, disabled=(up is None)):
825
+ st.session_state.preview_book = read_book_bytes(up.getvalue()) if up is not None else {}
826
+ st.session_state.show_preview_panel = True
827
+ st.rerun()
828
+
829
  go_btn = st.sidebar.button("Predict", type="primary", use_container_width=True)
830
  if st.sidebar.button("⬅ Back to Case Building", use_container_width=True): st.session_state.app_step="dev"; st.rerun()
831
 
832
  sticky_header("Prediction", "Upload a dataset with the 5 feature columns (no actual column).")
833
+ render_preview_panel() # top-of-page preview
834
 
835
  if go_btn and up is not None:
836
  if st.session_state.fitted_model is None:
 
875
  use_container_width=False, config={"displayModeBar": False, "scrollZoom": True})
876
  render_export_button(phase_key="predict")
877
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
878
  # =========================
879
  # Footer
880
  # =========================