davanstrien's picture
davanstrien HF staff
Update app.py
d3c85ed verified
import streamlit as st
import matplotlib.pyplot as plt
import numpy as np
def plot_parameter_space(
alpha,
beta,
xmin=0,
xmax=1,
ymin=0,
ymax=1,
npts=500,
max_iter=40,
scheme="prism",
draw_boundary=False,
):
X = np.linspace(xmax, xmin, npts, endpoint=False)
X = np.flipud(X)
Y = np.linspace(ymax, ymin, npts, endpoint=False)
U, V = np.meshgrid(X, Y)
Z = U + V * 1j
exit_times = max_iter * np.ones(Z.shape, np.int32)
mask = Z.imag < Z.real
exit_times[np.logical_not(mask)] = 0
for k in range(max_iter):
Z[mask] = (
Z[mask].imag / Z[mask].real
+ ((Z[mask].imag - 1) / Z[mask].real + np.floor(1 / Z[mask].real)) * 1j
)
old_mask = mask
mask = np.logical_and(Z.imag > 0, Z.imag < Z.real)
exit_times[mask ^ old_mask] = k + 1
fig, ax = plt.subplots()
ax.set_xlim((xmin, xmax))
ax.set_ylim((ymin, ymax))
exit_times[0, 0] = 0
im = ax.imshow(
exit_times,
cmap=scheme,
aspect="equal",
extent=(X.min(), X.max(), Y.min(), Y.max()),
)
ax.fill_between(X, X, 1.0, color=(1, 1, 1))
if draw_boundary:
for k in range(1, 16):
ax.plot([0, 1 / k], [1, 0], "k", lw=0.5)
ax.plot([1 / k, 1 / k], [1, 0], "k", lw=0.5)
ax.plot([1 / 2, 1], [0, 1 / k], "k", lw=0.5)
# Add a dot for the current alpha and beta values
ax.plot(alpha, beta, "ro", markersize=5, markeredgecolor="white")
ax.set_title("Parameter Space")
ax.set_xlabel("Alpha")
ax.set_ylabel("Beta")
return fig
def itm_image(alpha, beta, interval):
out = []
if interval[0] < 1 - alpha:
out.append((interval[0] + alpha, min(interval[1], 1 - alpha) + alpha))
if interval[0] < 1 - beta and interval[1] > 1 - alpha:
out.append(
(max(interval[0], 1 - alpha) + beta, min(interval[1], 1 - beta) + beta)
)
if interval[1] > 1 - beta:
out.append((max(interval[0], 1 - beta) + beta - 1, interval[1] + beta - 1))
return out
def plot_images(alpha, beta, nimages=100):
images = [(0, 1)]
fig, ax = plt.subplots()
for n in range(nimages):
beg, end = zip(*images)
ax.hlines([n / nimages] * len(beg), beg, end)
images_next = []
for image in images:
images_next.extend(itm_image(alpha, beta, image))
images = images_next
ax.set_title(f"alpha={alpha:.2f}, beta={beta:.2f}")
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.set_xlabel("x")
ax.set_ylabel("Iteration")
return fig
def main():
st.set_page_config(layout="wide")
st.title("Interactive Visualization of Interval Translation Maps")
st.sidebar.header("Controls")
# Initialize session state for alpha and beta if not already present
if "alpha" not in st.session_state:
st.session_state.alpha = 0.6
if "beta" not in st.session_state:
st.session_state.beta = 0.3
# Function to update alpha
def update_alpha(increment):
st.session_state.alpha = max(0, min(1, st.session_state.alpha + increment))
# Function to update beta
def update_beta(increment):
st.session_state.beta = max(0, min(1, st.session_state.beta + increment))
# Alpha control
st.sidebar.subheader("Alpha Control")
col1, col2, col3, col4, col5 = st.sidebar.columns([1, 1, 2, 1, 1])
with col1:
st.button("▼▼", on_click=update_alpha, args=(-0.1,), key="alpha_down_large")
with col2:
st.button("▼", on_click=update_alpha, args=(-0.01,), key="alpha_down")
with col3:
st.write(f"Alpha: {st.session_state.alpha:.2f}")
with col4:
st.button("▲", on_click=update_alpha, args=(0.01,), key="alpha_up")
with col5:
st.button("▲▲", on_click=update_alpha, args=(0.1,), key="alpha_up_large")
# Beta control
st.sidebar.subheader("Beta Control")
col1, col2, col3, col4, col5 = st.sidebar.columns([1, 1, 2, 1, 1])
with col1:
st.button("▼▼", on_click=update_beta, args=(-0.1,), key="beta_down_large")
with col2:
st.button("▼", on_click=update_beta, args=(-0.01,), key="beta_down")
with col3:
st.write(f"Beta: {st.session_state.beta:.2f}")
with col4:
st.button("▲", on_click=update_beta, args=(0.01,), key="beta_up")
with col5:
st.button("▲▲", on_click=update_beta, args=(0.1,), key="beta_up_large")
col1, col2 = st.columns(2)
with col1:
st.subheader("Parameter Space")
fig_param = plot_parameter_space(
st.session_state.alpha, st.session_state.beta, scheme="prism"
)
st.pyplot(fig_param)
with col2:
st.subheader("Image Plot")
fig_images = plot_images(st.session_state.alpha, st.session_state.beta)
st.pyplot(fig_images)
st.caption(
"Use the ▲/▲▲ and ▼/▼▼ buttons in the sidebar to adjust Alpha and Beta values. The red dot in the Parameter Space plot shows the current (Alpha, Beta) position."
)
st.markdown("""
## About this Visualization
This interactive tool visualizes Interval Translation Maps (ITMs) and their parameter space.
- The left plot shows the parameter space of ITMs. The red dot indicates the current (Alpha, Beta) values.
- The right plot displays the images of the interval [0,1] under repeated application of the ITM.
Use the up and down arrow buttons in the sidebar to adjust the alpha and beta parameters and observe how they affect both plots.
- Single arrows (▲/▼) change values by 0.01
- Double arrows (▲▲/▼▼) change values by 0.1
""")
if __name__ == "__main__":
main()