Skip to content

Commit 8aec2bc

Browse files
committed
fix: zoom BET and Rouquerol plots to the fitted window; default sample name to filename
1 parent afda044 commit 8aec2bc

1 file changed

Lines changed: 50 additions & 12 deletions

File tree

app_bet.py

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -269,20 +269,44 @@ def _plot_isotherm(ads, des, iso_cls, hyst_cls) -> plt.Figure:
269269

270270

271271
def _plot_rouquerol_transform(p_rel, n, best_window) -> plt.Figure:
272-
"""Plot n(1−p/p0) vs p/p0 with the selected BET window highlighted."""
272+
"""Plot n(1−p/p0) vs p/p0: full range plus a zoom on the selected BET window.
273+
274+
The full-range panel keeps the Rouquerol-transform maximum (which sets the
275+
upper BET bound); a second, zoomed panel is confined to the selected window
276+
so the four consistency criteria can actually be inspected. A second panel
277+
was chosen over an inset so the zoomed region is large enough to read and
278+
the two views do not overlap.
279+
"""
273280
setup_plot_style()
274-
fig, ax = plt.subplots(figsize=(5, 3.8))
281+
fig, (ax, ax_zoom) = plt.subplots(1, 2, figsize=(10, 3.8))
275282
t = rouquerol_transform(p_rel, n)
276-
ax.plot(p_rel, t, "o-", color=C_ADS, ms=4, lw=1.4, label="n(1−p/p₀)")
277-
if best_window is not None:
278-
ax.axvspan(best_window.p_min, best_window.p_max,
279-
alpha=0.18, color=C_BET, label="Selected BET range")
280-
ax.axvline(best_window.p_min, ls="--", lw=0.9, color=C_BET)
281-
ax.axvline(best_window.p_max, ls="--", lw=0.9, color=C_BET)
282-
ax.set_xlabel(r"$p/p_0$")
283-
ax.set_ylabel(r"$n(1-p/p_0)$ (cm³ g⁻¹)")
283+
284+
for a in (ax, ax_zoom):
285+
a.plot(p_rel, t, "o-", color=C_ADS, ms=4, lw=1.4, label="n(1−p/p₀)")
286+
if best_window is not None:
287+
a.axvspan(best_window.p_min, best_window.p_max,
288+
alpha=0.18, color=C_BET, label="Selected BET range")
289+
a.axvline(best_window.p_min, ls="--", lw=0.9, color=C_BET)
290+
a.axvline(best_window.p_max, ls="--", lw=0.9, color=C_BET)
291+
a.set_xlabel(r"$p/p_0$")
292+
a.set_ylabel(r"$n(1-p/p_0)$ (cm³ g⁻¹)")
293+
284294
ax.legend(fontsize=8)
285-
ax.set_title("Rouquerol Transform", fontsize=10)
295+
ax.set_title("Rouquerol Transform (full range)", fontsize=10)
296+
297+
if best_window is not None:
298+
margin = 0.1 * (best_window.p_max - best_window.p_min)
299+
ax_zoom.set_xlim(best_window.p_min - margin, best_window.p_max + margin)
300+
in_win = (p_rel >= best_window.p_min) & (p_rel <= best_window.p_max)
301+
if in_win.any():
302+
y_win = t[in_win]
303+
y_margin = 0.1 * (y_win.max() - y_win.min())
304+
ax_zoom.set_ylim(y_win.min() - y_margin, y_win.max() + y_margin)
305+
ax_zoom.legend(fontsize=8)
306+
ax_zoom.set_title("Selected BET range (zoomed)", fontsize=10)
307+
else:
308+
ax_zoom.set_title("Selected BET range", fontsize=10)
309+
286310
plt.tight_layout()
287311
return fig
288312

@@ -417,7 +441,8 @@ def _match_instrument_window_by_pressure(p_ads, n_ads, bet_pts,
417441
)
418442

419443
st.divider()
420-
sample_name = st.text_input("Sample name", value="Sample")
444+
default_sample = Path(uploaded.name).stem if uploaded is not None else "Sample"
445+
sample_name = st.text_input("Sample name", value=default_sample)
421446

422447
st.divider()
423448
st.subheader("⚙️ Options")
@@ -714,6 +739,19 @@ def _match_instrument_window_by_pressure(p_ads, n_ads, bet_pts,
714739
x_fit = np.linspace(bet_res["x"].min(), bet_res["x"].max(), 200)
715740
ax.plot(x_fit, bet_res["slope"] * x_fit + bet_res["intercept"],
716741
"-", color=C_BET, lw=1.6)
742+
# Limit the axes to the fitted window (plus a 10% margin) so the
743+
# regression is inspectable on microporous isotherms, where the unused
744+
# points at high p/p0 would otherwise compress the fitted region to a
745+
# flat strip. The margin is derived from the fitted points, not a fixed
746+
# constant.
747+
x_lo = float(bet_res["x"].min())
748+
x_hi = float(bet_res["x"].max())
749+
x_margin = 0.1 * (x_hi - x_lo)
750+
ax.set_xlim(x_lo - x_margin, x_hi + x_margin)
751+
y_lo = float(bet_res["y"].min())
752+
y_hi = float(bet_res["y"].max())
753+
y_margin = 0.1 * (y_hi - y_lo)
754+
ax.set_ylim(y_lo - y_margin, y_hi + y_margin)
717755
ax.set_xlabel(r"$p/p_0$")
718756
ax.set_ylabel(r"$1/[V_a(p_0/p-1)]$ (g cm$^{-3}$)")
719757
ax.legend(fontsize=8)

0 commit comments

Comments
 (0)