Skip to content

Commit aba57bb

Browse files
author
Daniel Precioso, PhD
committed
Add LaTeX formatting for initial conditions and update plot limits in Gierer-Meinhardt simulation
1 parent 26b801b commit aba57bb

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

streamlit/pages/02_Gierer_Meinhardt_1D.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,19 @@ def format_noise_equation(terms: tuple[tuple[str, int], ...]) -> str:
6262
return rf"\eta(x) = \frac{{1}}{{{len(pieces)}}}\left({joined}\right)"
6363

6464

65+
def format_initial_conditions_latex(terms: tuple[tuple[str, int], ...]) -> str:
66+
"""Return the perturbation and initial conditions as one LaTeX block."""
67+
noise_equation = format_noise_equation(terms)
68+
return rf"""
69+
\begin{{aligned}}
70+
{noise_equation} \\
71+
u(x, 0) &= u_* \left(1 + \varepsilon \eta(x)\right) \\
72+
v(x, 0) &= v_* \left(1 + \varepsilon \eta(x)\right) \\
73+
\varepsilon &= {PERTURBATION_AMPLITUDE:.2f}
74+
\end{{aligned}}
75+
"""
76+
77+
6578
def initialize_state(
6679
x: np.ndarray,
6780
a: float,
@@ -129,10 +142,28 @@ def simulate_gierer_meinhardt(
129142
return x, times, v_history
130143

131144

132-
def plot_profile(x: np.ndarray, values: np.ndarray, time_value: float) -> plt.Figure:
145+
def simulation_ylim(v_history: np.ndarray) -> tuple[float, float]:
146+
"""Return fixed y-limits based on the full stored simulation."""
147+
y_min = float(np.min(v_history))
148+
y_max = float(np.max(v_history))
149+
span = y_max - y_min
150+
if np.isclose(span, 0.0):
151+
margin = max(0.05 * max(abs(y_max), 1.0), 1e-3)
152+
else:
153+
margin = 0.05 * span
154+
return y_min - margin, y_max + margin
155+
156+
157+
def plot_profile(
158+
x: np.ndarray,
159+
values: np.ndarray,
160+
time_value: float,
161+
y_limits: tuple[float, float],
162+
) -> plt.Figure:
133163
"""Plot the inhibitor profile at one stored time."""
134164
fig, ax = plt.subplots(figsize=(9, 4))
135165
ax.plot(x, values, color="#1f77b4", linewidth=2)
166+
ax.set_ylim(*y_limits)
136167
ax.set_xlabel("x")
137168
ax.set_ylabel("v(x, t)")
138169
ax.set_title(f"Gierer-Meinhardt 1D, t = {time_value:.2f}")
@@ -237,11 +268,7 @@ def render_page() -> None:
237268
st.caption("The parameters b = 1 and gamma = 1 are fixed.")
238269
st.markdown("### Custom Perturbation")
239270
terms = render_term_controls()
240-
st.latex(format_noise_equation(terms))
241-
st.caption(
242-
"The initial condition is u(x, 0) = u_* [1 + epsilon eta(x)] and "
243-
"v(x, 0) = v_* [1 + epsilon eta(x)] with epsilon = 0.01."
244-
)
271+
st.latex(format_initial_conditions_latex(terms))
245272

246273
if st.button("Start", type="primary"):
247274
with st.spinner("Running 1000 stored time steps..."):
@@ -276,6 +303,7 @@ def render_page() -> None:
276303
simulation["x"],
277304
simulation["v_history"][time_index],
278305
float(simulation["times"][time_index]),
306+
simulation_ylim(simulation["v_history"]),
279307
)
280308
st.pyplot(figure)
281309
plt.close(figure)

0 commit comments

Comments
 (0)