Skip to content

Commit 16261f5

Browse files
HMNS19tpike3
authored andcommitted
Add render interval slider to control visualization update frequency (projectmesa#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.
1 parent 804ea95 commit 16261f5

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

mesa/visualization/solara_viz.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def SolaraViz(
5252
| Literal["default"] = "default",
5353
*,
5454
play_interval: int = 100,
55+
render_interval: int = 1,
5556
simulator: Simulator | None = None,
5657
model_params=None,
5758
name: str | None = None,
@@ -72,6 +73,8 @@ def SolaraViz(
7273
Defaults to "default", which uses the default Altair space visualization.
7374
play_interval (int, optional): Interval for playing the model steps in milliseconds.
7475
This controls the speed of the model's automatic stepping. Defaults to 100 ms.
76+
render_interval (int, optional): Controls how often plots are updated during a simulation,
77+
allowing users to skip intermediate steps and update graphs less frequently.
7578
simulator: A simulator that controls the model (optional)
7679
model_params (dict, optional): Parameters for (re-)instantiating a model.
7780
Can include user-adjustable parameters and fixed parameters. Defaults to None.
@@ -90,6 +93,8 @@ def SolaraViz(
9093
model instance is provided, it will be converted to a reactive model using `solara.use_reactive`.
9194
- The `play_interval` argument controls the speed of the model's automatic stepping. A lower
9295
value results in faster stepping, while a higher value results in slower stepping.
96+
- The `render_interval` argument determines how often plots are updated during simulation. Higher values
97+
reduce update frequency,resulting in faster execution.
9398
"""
9499
if components == "default":
95100
components = [components_altair.make_altair_space()]
@@ -103,7 +108,7 @@ def SolaraViz(
103108
# set up reactive model_parameters shared by ModelCreator and ModelController
104109
reactive_model_parameters = solara.use_reactive({})
105110
reactive_play_interval = solara.use_reactive(play_interval)
106-
111+
reactive_render_interval = solara.use_reactive(render_interval)
107112
with solara.AppBar():
108113
solara.AppBarTitle(name if name else model.value.__class__.__name__)
109114

@@ -117,18 +122,28 @@ def SolaraViz(
117122
max=500,
118123
step=10,
119124
)
125+
solara.SliderInt(
126+
label="Render Interval (steps)",
127+
value=reactive_render_interval,
128+
on_value=lambda v: reactive_render_interval.set(v),
129+
min=1,
130+
max=100,
131+
step=2,
132+
)
120133
if not isinstance(simulator, Simulator):
121134
ModelController(
122135
model,
123136
model_parameters=reactive_model_parameters,
124137
play_interval=reactive_play_interval,
138+
render_interval=reactive_render_interval,
125139
)
126140
else:
127141
SimulatorController(
128142
model,
129143
simulator,
130144
model_parameters=reactive_model_parameters,
131145
play_interval=reactive_play_interval,
146+
render_interval=reactive_render_interval,
132147
)
133148
with solara.Card("Model Parameters"):
134149
ModelCreator(
@@ -189,14 +204,15 @@ def ModelController(
189204
*,
190205
model_parameters: dict | solara.Reactive[dict] = None,
191206
play_interval: int | solara.Reactive[int] = 100,
207+
render_interval: int | solara.Reactive[int] = 1,
192208
):
193209
"""Create controls for model execution (step, play, pause, reset).
194210
195211
Args:
196212
model: Reactive model instance
197213
model_parameters: Reactive parameters for (re-)instantiating a model.
198214
play_interval: Interval for playing the model steps in milliseconds.
199-
215+
render_interval: Controls how often the plots are updated during simulation steps.Higher value reduce update frequency.
200216
"""
201217
playing = solara.use_reactive(False)
202218
running = solara.use_reactive(True)
@@ -215,9 +231,12 @@ async def step():
215231

216232
@function_logger(__name__)
217233
def do_step():
218-
"""Advance the model by one step."""
219-
model.value.step()
234+
"""Advance the model by the number of steps specified by the render_interval slider."""
235+
for _ in range(render_interval.value):
236+
model.value.step()
237+
220238
running.value = model.value.running
239+
221240
force_update()
222241

223242
@function_logger(__name__)
@@ -259,6 +278,7 @@ def SimulatorController(
259278
*,
260279
model_parameters: dict | solara.Reactive[dict] = None,
261280
play_interval: int | solara.Reactive[int] = 100,
281+
render_interval: int | solara.Reactive[int] = 1,
262282
):
263283
"""Create controls for model execution (step, play, pause, reset).
264284
@@ -267,7 +287,11 @@ def SimulatorController(
267287
simulator: Simulator instance
268288
model_parameters: Reactive parameters for (re-)instantiating a model.
269289
play_interval: Interval for playing the model steps in milliseconds.
290+
render_interval: Controls how often the plots are updated during simulation steps.Higher values reduce update frequency.
270291
292+
Notes:
293+
The `step button` increments the step by the value specified in the `render_interval` slider.
294+
This behavior ensures synchronization between simulation steps and plot updates.
271295
"""
272296
playing = solara.use_reactive(False)
273297
running = solara.use_reactive(True)
@@ -285,8 +309,8 @@ async def step():
285309
)
286310

287311
def do_step():
288-
"""Advance the model by one step."""
289-
simulator.run_for(1)
312+
"""Advance the model by the number of steps specified by the render_interval slider."""
313+
simulator.run_for(render_interval.value)
290314
running.value = model.value.running
291315
force_update()
292316

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

0 commit comments

Comments
 (0)