UCS2014 commited on
Commit
65ff775
·
verified ·
1 Parent(s): 2499de7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -98
app.py CHANGED
@@ -26,11 +26,14 @@ MODEL_FALLBACKS = [MODELS_DIR / "model.joblib", MODELS_DIR / "model.pkl"]
26
  COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
27
 
28
  # ---- Plot sizing controls ----
29
- CROSS_W = 350; CROSS_H = 350 # square cross-plot
30
- TRACK_W = 400; TRACK_H = 950 # log-strip style
 
 
31
  FONT_SZ = 15
32
- PLOT_COLS = [30, 1, 20] # left spacer right
33
- CROSS_NUDGE = 0.02
 
34
 
35
  # =========================
36
  # Page / CSS
@@ -167,131 +170,59 @@ def _nice_tick0(xmin: float, step: int = 100) -> float:
167
  # =========================
168
  # Cross-plot (Matplotlib, static)
169
  # =========================
 
 
 
170
  def cross_plot_static(actual, pred):
171
- a = pd.Series(actual).astype(float)
172
- p = pd.Series(pred).astype(float)
173
 
174
  fixed_min, fixed_max = 6000, 10000
175
- ticks = np.arange(6000, 10001, 1000)
176
 
177
- fig, ax = plt.subplots(figsize=(CROSS_W/100, CROSS_H/100), dpi=100)
 
 
 
 
 
178
 
179
- ax.scatter(a, p, s=14, c=COLORS["pred"], alpha=0.9, edgecolors="none")
 
180
 
181
  # 1:1 diagonal
182
  ax.plot([fixed_min, fixed_max], [fixed_min, fixed_max],
183
  linestyle="--", linewidth=1.2, color=COLORS["ref"])
184
 
185
- # Limits and ticks
186
  ax.set_xlim(fixed_min, fixed_max)
187
  ax.set_ylim(fixed_min, fixed_max)
188
  ax.set_xticks(ticks)
189
  ax.set_yticks(ticks)
190
 
191
- # Equal aspect for true 45°
192
- ax.set_aspect('equal', adjustable='box')
193
 
194
- # Thousands formatter
195
  fmt = FuncFormatter(lambda x, _: f"{int(x):,}")
196
  ax.xaxis.set_major_formatter(fmt)
197
  ax.yaxis.set_major_formatter(fmt)
198
 
199
- # Labels (bold, larger)
200
  ax.set_xlabel("Actual UCS (psi)", fontweight="bold", fontsize=16)
201
  ax.set_ylabel("Predicted UCS (psi)", fontweight="bold", fontsize=16)
202
 
203
- # Grid & frame
204
  ax.grid(True, linestyle=":", alpha=0.35)
205
  for spine in ax.spines.values():
206
- spine.set_visible(True)
207
  spine.set_linewidth(1.2)
208
  spine.set_color("#444")
209
 
210
- fig.tight_layout()
211
- return fig
212
 
213
- # =========================
214
- # Track plot (Plotly)
215
- # =========================
216
- def track_plot(df, include_actual=True):
217
- depth_col = next((c for c in df.columns if 'depth' in str(c).lower()), None)
218
- if depth_col is not None:
219
- y = pd.Series(df[depth_col]).astype(float)
220
- ylab = depth_col
221
- y_range = [float(y.max()), float(y.min())] # reverse
222
- else:
223
- y = pd.Series(np.arange(1, len(df) + 1))
224
- ylab = "Point Index"
225
- y_range = [float(y.max()), float(y.min())]
226
-
227
- # X (UCS) range & ticks
228
- x_series = pd.Series(df.get("UCS_Pred", pd.Series(dtype=float))).astype(float)
229
- if include_actual and TARGET in df.columns:
230
- x_series = pd.concat([x_series, pd.Series(df[TARGET]).astype(float)], ignore_index=True)
231
- x_lo, x_hi = float(x_series.min()), float(x_series.max())
232
- x_pad = 0.03 * (x_hi - x_lo if x_hi > x_lo else 1.0)
233
- xmin, xmax = x_lo - x_pad, x_hi + x_pad
234
- tick0 = _nice_tick0(xmin, step=100)
235
-
236
- fig = go.Figure()
237
- fig.add_trace(go.Scatter(
238
- x=df["UCS_Pred"], y=y, mode="lines",
239
- line=dict(color=COLORS["pred"], width=1.8),
240
- name="UCS_Pred",
241
- hovertemplate="UCS_Pred: %{x:.0f}<br>"+ylab+": %{y}<extra></extra>"
242
- ))
243
- if include_actual and TARGET in df.columns:
244
- fig.add_trace(go.Scatter(
245
- x=df[TARGET], y=y, mode="lines",
246
- line=dict(color=COLORS["actual"], width=2.0, dash="dot"),
247
- name="UCS (actual)",
248
- hovertemplate="UCS (actual): %{x:.0f}<br>"+ylab+": %{y}<extra></extra>"
249
- ))
250
-
251
- fig.update_layout(
252
- width=TRACK_W, height=TRACK_H, paper_bgcolor="#fff", plot_bgcolor="#fff",
253
- margin=dict(l=72, r=18, t=36, b=48), hovermode="closest",
254
- font=dict(size=FONT_SZ),
255
- legend=dict(
256
- x=0.98, y=0.05, xanchor="right", yanchor="bottom",
257
- bgcolor="rgba(255,255,255,0.75)", bordercolor="#ccc", borderwidth=1
258
- ),
259
- legend_title_text=""
260
- )
261
- fig.update_xaxes(
262
- title_text="<b>UCS (psi)</b>", title_font=dict(size=18),
263
- side="top", range=[xmin, xmax],
264
- ticks="outside", tickformat=",.0f", tickmode="auto", tick0=tick0,
265
- showline=True, linewidth=1.2, linecolor="#444", mirror=True,
266
- showgrid=True, gridcolor="rgba(0,0,0,0.12)", automargin=True
267
- )
268
- fig.update_yaxes(
269
- title_text=f"<b>{ylab}</b>", title_font=dict(size=18),
270
- range=y_range, ticks="outside",
271
- showline=True, linewidth=1.2, linecolor="#444", mirror=True,
272
- showgrid=True, gridcolor="rgba(0,0,0,0.12)", automargin=True
273
- )
274
  return fig
275
 
276
- # ---------- Preview modal (matplotlib) ----------
277
- def preview_tracks(df: pd.DataFrame, cols: list[str]):
278
- cols = [c for c in cols if c in df.columns]
279
- n = len(cols)
280
- if n == 0:
281
- fig, ax = plt.subplots(figsize=(4, 2))
282
- ax.text(0.5,0.5,"No selected columns",ha="center",va="center")
283
- ax.axis("off")
284
- return fig
285
- fig, axes = plt.subplots(1, n, figsize=(2.2*n, 7.0), sharey=True, dpi=100)
286
- if n == 1: axes = [axes]
287
- idx = np.arange(1, len(df) + 1)
288
- for ax, col in zip(axes, cols):
289
- ax.plot(df[col], idx, '-', lw=1.4, color="#333")
290
- ax.set_xlabel(col); ax.xaxis.set_label_position('top'); ax.xaxis.tick_top(); ax.invert_yaxis()
291
- ax.grid(True, linestyle=":", alpha=0.3)
292
- for s in ax.spines.values(): s.set_visible(True)
293
- axes[0].set_ylabel("Point Index")
294
- return fig
295
 
296
  try:
297
  dialog = st.dialog
 
26
  COLORS = {"pred": "#1f77b4", "actual": "#f2b702", "ref": "#5a5a5a"}
27
 
28
  # ---- Plot sizing controls ----
29
+ CROSS_W = None # let the chart fill the column
30
+ CROSS_H = 420
31
+ TRACK_W = None # let the chart fill the column
32
+ TRACK_H = 820
33
  FONT_SZ = 15
34
+ PLOT_COLS = [42, 2, 30] # wider left & right, a thicker spacer in the middle
35
+ CROSS_NUDGE = 0.0
36
+
37
 
38
  # =========================
39
  # Page / CSS
 
170
  # =========================
171
  # Cross-plot (Matplotlib, static)
172
  # =========================
173
+ # =========================
174
+ # Cross plot (Matplotlib, fixed limits & ticks)
175
+ # =========================
176
  def cross_plot_static(actual, pred):
177
+ a = pd.Series(actual, dtype=float)
178
+ p = pd.Series(pred, dtype=float)
179
 
180
  fixed_min, fixed_max = 6000, 10000
181
+ ticks = np.arange(fixed_min, fixed_max + 1, 1000)
182
 
183
+ # use constrained_layout + generous margins so big labels never overlap
184
+ fig, ax = plt.subplots(
185
+ figsize=((CROSS_W or 500)/100, (CROSS_H or 500)/100),
186
+ dpi=100,
187
+ constrained_layout=True
188
+ )
189
 
190
+ # points
191
+ ax.scatter(a, p, s=18, c=COLORS["pred"], alpha=0.9, linewidths=0)
192
 
193
  # 1:1 diagonal
194
  ax.plot([fixed_min, fixed_max], [fixed_min, fixed_max],
195
  linestyle="--", linewidth=1.2, color=COLORS["ref"])
196
 
197
+ # identical axes limits + ticks
198
  ax.set_xlim(fixed_min, fixed_max)
199
  ax.set_ylim(fixed_min, fixed_max)
200
  ax.set_xticks(ticks)
201
  ax.set_yticks(ticks)
202
 
203
+ # equal aspect true 45° reference
204
+ ax.set_aspect("equal", adjustable="box")
205
 
206
+ # thousands formatting
207
  fmt = FuncFormatter(lambda x, _: f"{int(x):,}")
208
  ax.xaxis.set_major_formatter(fmt)
209
  ax.yaxis.set_major_formatter(fmt)
210
 
211
+ # labels (bold, larger)
212
  ax.set_xlabel("Actual UCS (psi)", fontweight="bold", fontsize=16)
213
  ax.set_ylabel("Predicted UCS (psi)", fontweight="bold", fontsize=16)
214
 
215
+ # grid & frame
216
  ax.grid(True, linestyle=":", alpha=0.35)
217
  for spine in ax.spines.values():
 
218
  spine.set_linewidth(1.2)
219
  spine.set_color("#444")
220
 
221
+ # extra room for the large labels
222
+ fig.subplots_adjust(left=0.23, bottom=0.20, right=0.98, top=0.98)
223
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  return fig
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
  try:
228
  dialog = st.dialog