I want to implement a "reset" function activated by a "reset" button in a Shiny app, that would set all input variables back to their initial status (as they were when launching the app), and update any subsequent functions/plots depending on these inputs.
A reproducible example is the one provided on Shiny for Python website using the function reactive.isolate, showing a histogram which updates upon the user selecting observation values and then clicking on "GO".
import matplotlib.pyplot as plt
import numpy as np
from shiny import App, Inputs, Outputs, Session, reactive, render, ui
app_ui = ui.page_fluid(
ui.input_slider("n", "Number of observations", min=0, max=1000, value=500),
ui.input_action_button("go", "Go!", class_="btn-success"),
ui.output_plot("plot"),
)
def server(input: Inputs, output: Outputs, session: Session):
@output
@render.plot(alt="A histogram")
def plot():
# Take a reactive dependency on the action button...
input.go()
# ...but don't take a reactive dependency on the slider
with reactive.isolate():
np.random.seed(19680801)
x = 100 + 15 * np.random.randn(input.n())
fig, ax = plt.subplots()
ax.hist(x, bins=30, density=True)
return fig
app = App(app_ui, server)
I want to create a "Reset" button which, upon clicking, would return the "Number of Observations" back to 500 and would update the histogram back to its original state when launching the app.
Upon creating the button,
app_ui = ui.page_fluid(
ui.input_slider("n", "Number of observations", min=0, max=1000, value=500),
ui.input_action_button("go", "Go!", class_="btn-success"),
ui.input_action_button("reset", "Reset", class_="btn-success"),
ui.output_plot("plot"),
)
I tried to use the input.reset() status in a separate function and tag the def plot() with @reactive.Effect (tried as well with @reactive.Calc or @reactive.event(input.reset) but without success.
Clicking on the Reset button will set back the field "number of observations" to 500, but the histogram will not update automatically, unless I then click on "Go". IDeally, clicking "Reset" would update both the value and the plot without the extra "Go" click
def server(input: Inputs, output: Outputs, session: Session):
@reactive.Effect
@output
@render.plot(alt="A histogram")
def plot():
# Take a reactive dependency on the action button...
input.go()
# ...but don't take a reactive dependency on the slider
with reactive.isolate():
np.random.seed(19680801)
x = 100 + 15 * np.random.randn(input.n())
fig, ax = plt.subplots()
ax.hist(x, bins=30, density=True)
return fig
@reactive.Effect
@reactive.event(input.reset )
def _():
ui.update_slider( "n" , value = 500 )
app = App(app_ui, server)
Truly grateful for any help !
I found the answer in the meanwhile so posting here for anyone who may face the same problem.
The key is to create a reactive.value() at the very beginning to save the number of observations (500) and use it then in two separate functions for "go" and "reset" respectively.