-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Output multiple ui elements from one function call #1795
Comments
Are you using the same or different slices of the dataframe in each of the three outputs? In general, I'd recommend replacing the expensive function with a reactive.calc. This is a reactive function that can use inputs or other reactive values and updates automatically when the inputs change. If you move the expensive computation into the Here's an example that I think mimics your problem. I have an Slow appfrom shiny import App, reactive, render, ui
import time
import pandas as pd
import numpy as np
app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_slider("n", "Size of Dataset (x1,000)", min = 0, max = 25, value = 10),
ui.input_action_button("compute", "Compute"),
ui.p("Click to run expensive computation"),
),
ui.output_text("result1"),
ui.output_text("result2"),
ui.output_text("result3"),
)
def expensive_calculation(n = 1000):
time.sleep(2)
data = pd.DataFrame({
'A': np.random.randn(n * 1000),
'B': np.random.randn(n * 1000)
})
return {
'mean_a': data['A'].mean(),
'mean_b': data['B'].mean(),
'total_rows': len(data)
}
def server(input, output, session):
@render.text
@reactive.event(input.compute)
def result1():
results = expensive_calculation(input.n())
return f"Mean of A: {results['mean_a']:.2f}"
@render.text
@reactive.event(input.compute)
def result2():
results = expensive_calculation(input.n())
return f"Mean of B: {results['mean_b']:.2f}"
@render.text
@reactive.event(input.compute)
def result3():
results = expensive_calculation(input.n())
return f"Total rows: {results['total_rows']}"
app = App(app_ui, server) If we make the from shiny import App, reactive, render, ui
import time
import pandas as pd
import numpy as np
app_ui = ui.page_sidebar(
ui.sidebar(
ui.input_slider("n", "Size of Dataset (x1,000)", min=0, max=25, value=10),
ui.input_action_button("compute", "Compute"),
ui.p("Click to run expensive computation"),
),
ui.output_text("result1"),
ui.output_text("result2"),
ui.output_text("result3"),
)
def server(input, output, session):
@reactive.calc
@reactive.event(input.compute)
def expensive_calculation():
n = input.n() * 1000
time.sleep(2)
data = pd.DataFrame({"A": np.random.randn(n), "B": np.random.randn(n)})
return {
"mean_a": data["A"].mean(),
"mean_b": data["B"].mean(),
"total_rows": len(data),
}
@render.text
def result1():
results = expensive_calculation()
return f"Mean of A: {results['mean_a']:.2f}"
@render.text
def result2():
results = expensive_calculation()
return f"Mean of B: {results['mean_b']:.2f}"
@render.text
def result3():
results = expensive_calculation()
return f"Total rows: {results['total_rows']}"
app = App(app_ui, server) |
This is perfect, thanks! The three things being returned aren't all slices from the same dataframe but a substantial amount of time is saved by the reactive calculation! |
Hi! This could be extremely obvious but I can't find anything that jumps out explicitly to me in the API reference. I have a single, computationally expensive function that does operations on a large dataframe and returns various slices from it at the end. It currently returns 3 values. At the moment I am calling the function 3 times to output 3 different @reactive_event widgets. I feel like the reactivity itself doesn't handle this but I am curious what the best way to avoid excessive computations is when a single function is returning multiple outputs when the output IDs have to be unique.
Sorry if this is super obvious (probably is :) )
The text was updated successfully, but these errors were encountered: