Skip to content

Commit

Permalink
Add render interval slider to control visualization update frequency (#…
Browse files Browse the repository at this point in the history
…2596)

This PR adds a render interval slider to the SolaraViz visualization system, allowing users to control how frequently plots and visualizations are updated during model simulation. This feature significantly improves performance when working with complex visualizations or multiple plots.
  • Loading branch information
HMNS19 authored Jan 10, 2025
1 parent baf5c87 commit 3a85213
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions mesa/visualization/solara_viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def SolaraViz(
| Literal["default"] = "default",
*,
play_interval: int = 100,
render_interval: int = 1,
simulator: Simulator | None = None,
model_params=None,
name: str | None = None,
Expand All @@ -72,6 +73,8 @@ def SolaraViz(
Defaults to "default", which uses the default Altair space visualization.
play_interval (int, optional): Interval for playing the model steps in milliseconds.
This controls the speed of the model's automatic stepping. Defaults to 100 ms.
render_interval (int, optional): Controls how often plots are updated during a simulation,
allowing users to skip intermediate steps and update graphs less frequently.
simulator: A simulator that controls the model (optional)
model_params (dict, optional): Parameters for (re-)instantiating a model.
Can include user-adjustable parameters and fixed parameters. Defaults to None.
Expand All @@ -90,6 +93,8 @@ def SolaraViz(
model instance is provided, it will be converted to a reactive model using `solara.use_reactive`.
- The `play_interval` argument controls the speed of the model's automatic stepping. A lower
value results in faster stepping, while a higher value results in slower stepping.
- The `render_interval` argument determines how often plots are updated during simulation. Higher values
reduce update frequency,resulting in faster execution.
"""
if components == "default":
components = [components_altair.make_altair_space()]
Expand All @@ -103,7 +108,7 @@ def SolaraViz(
# set up reactive model_parameters shared by ModelCreator and ModelController
reactive_model_parameters = solara.use_reactive({})
reactive_play_interval = solara.use_reactive(play_interval)

reactive_render_interval = solara.use_reactive(render_interval)
with solara.AppBar():
solara.AppBarTitle(name if name else model.value.__class__.__name__)

Expand All @@ -117,18 +122,28 @@ def SolaraViz(
max=500,
step=10,
)
solara.SliderInt(
label="Render Interval (steps)",
value=reactive_render_interval,
on_value=lambda v: reactive_render_interval.set(v),
min=1,
max=100,
step=2,
)
if not isinstance(simulator, Simulator):
ModelController(
model,
model_parameters=reactive_model_parameters,
play_interval=reactive_play_interval,
render_interval=reactive_render_interval,
)
else:
SimulatorController(
model,
simulator,
model_parameters=reactive_model_parameters,
play_interval=reactive_play_interval,
render_interval=reactive_render_interval,
)
with solara.Card("Model Parameters"):
ModelCreator(
Expand Down Expand Up @@ -189,14 +204,15 @@ def ModelController(
*,
model_parameters: dict | solara.Reactive[dict] = None,
play_interval: int | solara.Reactive[int] = 100,
render_interval: int | solara.Reactive[int] = 1,
):
"""Create controls for model execution (step, play, pause, reset).
Args:
model: Reactive model instance
model_parameters: Reactive parameters for (re-)instantiating a model.
play_interval: Interval for playing the model steps in milliseconds.
render_interval: Controls how often the plots are updated during simulation steps.Higher value reduce update frequency.
"""
playing = solara.use_reactive(False)
running = solara.use_reactive(True)
Expand All @@ -215,9 +231,12 @@ async def step():

@function_logger(__name__)
def do_step():
"""Advance the model by one step."""
model.value.step()
"""Advance the model by the number of steps specified by the render_interval slider."""
for _ in range(render_interval.value):
model.value.step()

running.value = model.value.running

force_update()

@function_logger(__name__)
Expand Down Expand Up @@ -259,6 +278,7 @@ def SimulatorController(
*,
model_parameters: dict | solara.Reactive[dict] = None,
play_interval: int | solara.Reactive[int] = 100,
render_interval: int | solara.Reactive[int] = 1,
):
"""Create controls for model execution (step, play, pause, reset).
Expand All @@ -267,7 +287,11 @@ def SimulatorController(
simulator: Simulator instance
model_parameters: Reactive parameters for (re-)instantiating a model.
play_interval: Interval for playing the model steps in milliseconds.
render_interval: Controls how often the plots are updated during simulation steps.Higher values reduce update frequency.
Notes:
The `step button` increments the step by the value specified in the `render_interval` slider.
This behavior ensures synchronization between simulation steps and plot updates.
"""
playing = solara.use_reactive(False)
running = solara.use_reactive(True)
Expand All @@ -285,8 +309,8 @@ async def step():
)

def do_step():
"""Advance the model by one step."""
simulator.run_for(1)
"""Advance the model by the number of steps specified by the render_interval slider."""
simulator.run_for(render_interval.value)
running.value = model.value.running
force_update()

Expand Down Expand Up @@ -390,7 +414,6 @@ def ModelCreator(
or are dictionaries containing parameter details such as type, value, min, and max.
- The `seed` argument ensures reproducibility by setting the initial seed for the model's random number generator.
- The component provides an interface for adjusting user-defined parameters and reseeding the model.
"""
if model_parameters is None:
model_parameters = {}
Expand Down

0 comments on commit 3a85213

Please sign in to comment.