Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion docs/tutorials/4_visualization_basic.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,42 @@
"> You can make the small window full screen by clicking the button in the top-right corner of the title bar."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Page Tab View\n",
"\n",
"#### **Plot Components**\n",
"You can place different components (except the renderer) on separate pages according to your preference. There are no restrictions on page numbering — pages do not need to be sequential or positive. Each page acts as an independent window where components may or may not exist.\n",
"\n",
"The default page is `page=0`. If pages are not sequential (e.g., `page=1` and `page=10`), the system will automatically create the 8 empty pages in between to maintain consistent indexing. To avoid empty pages in your dashboard, use sequential page numbers.\n",
"\n",
"To assign a plot component to a specific page, pass the `page` keyword argument to `make_plot_component`. For example, the following will display the plot component on page 1:\n",
"\n",
"```python\n",
"plot_comp = make_plot_component(\"encoding\", page=1)\n",
"```\n",
"\n",
"#### **Custom Components**\n",
"In tutorial 8, you will learn how to create custom components for the Solara dashboard. If you want a custom component to appear on a specific page, you must pass it as a tuple containing the component and the page number.\n",
"\n",
"```python\n",
"@solara.component\n",
"def CustomComponent():\n",
" ...\n",
"\n",
"page = SolaraViz(\n",
" model,\n",
" renderer,\n",
" components=[(CustomComponent, 1)] # Custom component will appear on page 1\n",
")\n",
"```\n",
"\n",
"> ⚠️ **Warning**\n",
"> Running the model can be performance-intensive. It is strongly recommended to pause the model in the dashboard before switching pages."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -282,7 +318,7 @@
" agent_portrayal=agent_portrayal\n",
")\n",
"\n",
"GiniPlot = make_plot_component(\"Gini\")\n",
"GiniPlot = make_plot_component(\"Gini\", page=1)\n",
"\n",
"page = SolaraViz(\n",
" money_model,\n",
Expand Down
36 changes: 36 additions & 0 deletions docs/tutorials/5_visualization_dynamic_agents.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,42 @@
"3. Press reset "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Page Tab View\n",
"\n",
"#### **Plot Components**\n",
"You can place different components (except the renderer) on separate pages according to your preference. There are no restrictions on page numbering — pages do not need to be sequential or positive. Each page acts as an independent window where components may or may not exist.\n",
"\n",
"The default page is `page=0`. If pages are not sequential (e.g., `page=1` and `page=10`), the system will automatically create the 8 empty pages in between to maintain consistent indexing. To avoid empty pages in your dashboard, use sequential page numbers.\n",
"\n",
"To assign a plot component to a specific page, pass the `page` keyword argument to `make_plot_component`. For example, the following will display the plot component on page 1:\n",
"\n",
"```python\n",
"plot_comp = make_plot_component(\"encoding\", page=1)\n",
"```\n",
"\n",
"#### **Custom Components**\n",
"In tutorial 8, you will learn how to create custom components for the Solara dashboard. If you want a custom component to appear on a specific page, you must pass it as a tuple containing the component and the page number.\n",
"\n",
"```python\n",
"@solara.component\n",
"def CustomComponent():\n",
" ...\n",
"\n",
"page = SolaraViz(\n",
" model,\n",
" renderer,\n",
" components=[(CustomComponent, 1)] # Custom component will appear on page 1\n",
")\n",
"```\n",
"\n",
"> ⚠️ **Warning**\n",
"> Running the model can be performance-intensive. It is strongly recommended to pause the model in the dashboard before switching pages."
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
36 changes: 36 additions & 0 deletions docs/tutorials/6_visualization_rendering_with_space_renderer.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,42 @@
" * It also ensures the visualization only updates at fixed intervals, improving performance and responsiveness during rapid simulations."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Page Tab View\n",
"\n",
"#### **Plot Components**\n",
"You can place different components (except the renderer) on separate pages according to your preference. There are no restrictions on page numbering — pages do not need to be sequential or positive. Each page acts as an independent window where components may or may not exist.\n",
"\n",
"The default page is `page=0`. If pages are not sequential (e.g., `page=1` and `page=10`), the system will automatically create the 8 empty pages in between to maintain consistent indexing. To avoid empty pages in your dashboard, use sequential page numbers.\n",
"\n",
"To assign a plot component to a specific page, pass the `page` keyword argument to `make_plot_component`. For example, the following will display the plot component on page 1:\n",
"\n",
"```python\n",
"plot_comp = make_plot_component(\"encoding\", page=1)\n",
"```\n",
"\n",
"#### **Custom Components**\n",
"In tutorial 8, you will learn how to create custom components for the Solara dashboard. If you want a custom component to appear on a specific page, you must pass it as a tuple containing the component and the page number.\n",
"\n",
"```python\n",
"@solara.component\n",
"def CustomComponent():\n",
" ...\n",
"\n",
"page = SolaraViz(\n",
" model,\n",
" renderer,\n",
" components=[(CustomComponent, 1)] # Custom component will appear on page 1\n",
")\n",
"```\n",
"\n",
"> ⚠️ **Warning**\n",
"> Running the model can be performance-intensive. It is strongly recommended to pause the model in the dashboard before switching pages."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
36 changes: 36 additions & 0 deletions docs/tutorials/7_visualization_propertylayer_visualization.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,42 @@
" * It also ensures the visualization only updates at fixed intervals, improving performance and responsiveness during rapid simulations."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Page Tab View\n",
"\n",
"#### **Plot Components**\n",
"You can place different components (except the renderer) on separate pages according to your preference. There are no restrictions on page numbering — pages do not need to be sequential or positive. Each page acts as an independent window where components may or may not exist.\n",
"\n",
"The default page is `page=0`. If pages are not sequential (e.g., `page=1` and `page=10`), the system will automatically create the 8 empty pages in between to maintain consistent indexing. To avoid empty pages in your dashboard, use sequential page numbers.\n",
"\n",
"To assign a plot component to a specific page, pass the `page` keyword argument to `make_plot_component`. For example, the following will display the plot component on page 1:\n",
"\n",
"```python\n",
"plot_comp = make_plot_component(\"encoding\", page=1)\n",
"```\n",
"\n",
"#### **Custom Components**\n",
"In the next tutorial, you will learn how to create custom components for the Solara dashboard. If you want a custom component to appear on a specific page, you must pass it as a tuple containing the component and the page number.\n",
"\n",
"```python\n",
"@solara.component\n",
"def CustomComponent():\n",
" ...\n",
"\n",
"page = SolaraViz(\n",
" model,\n",
" renderer,\n",
" components=[(CustomComponent, 1)] # Custom component will appear on page 1\n",
")\n",
"```\n",
"\n",
"> ⚠️ **Warning**\n",
"> Running the model can be performance-intensive. It is strongly recommended to pause the model in the dashboard before switching pages."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
41 changes: 39 additions & 2 deletions docs/tutorials/8_visualization_custom.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,43 @@
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Page Tab View\n",
"\n",
"#### **Plot Components**\n",
" \n",
"You can place different components (except the renderer) on separate pages according to your preference. There are no restrictions on page numbering — pages do not need to be sequential or positive. Each page acts as an independent window where components may or may not exist.\n",
"\n",
"The default page is `page=0`. If pages are not sequential (e.g., `page=1` and `page=10`), the system will automatically create the 8 empty pages in between to maintain consistent indexing. To avoid empty pages in your dashboard, use sequential page numbers.\n",
"\n",
"To assign a plot component to a specific page, pass the `page` keyword argument to `make_plot_component`. For example, the following will display the plot component on page 1:\n",
"\n",
"```python\n",
"plot_comp = make_plot_component(\"encoding\", page=1)\n",
"```\n",
"\n",
"#### **Custom Components**\n",
"If you want a custom component to appear on a specific page, you must pass it as a tuple containing the component and the page number.\n",
"\n",
"```python\n",
"@solara.component\n",
"def CustomComponent():\n",
" ...\n",
"\n",
"page = SolaraViz(\n",
" model,\n",
" renderer,\n",
" components=[(CustomComponent, 1)] # Custom component will appear on page 1\n",
")\n",
"```\n",
"\n",
"> ⚠️ **Warning**\n",
"> Running the model can be performance-intensive. It is strongly recommended to pause the model in the dashboard before switching pages."
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -305,11 +342,11 @@
"money_model = MoneyModel(n=50, width=10, height=10)\n",
"\n",
"SpaceGraph = make_space_component(agent_portrayal)\n",
"GiniPlot = make_plot_component(\"Gini\")\n",
"GiniPlot = make_plot_component(\"Gini\", page=1)\n",
"\n",
"page = SolaraViz(\n",
" money_model,\n",
" components=[SpaceGraph, GiniPlot, Histogram],\n",
" components=[SpaceGraph, GiniPlot, (Histogram, 2)],\n",
" model_params=model_params,\n",
" name=\"Boltzmann Wealth Model\",\n",
")\n",
Expand Down
6 changes: 4 additions & 2 deletions mesa/examples/advanced/sugarscape_g1mt/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ def post_process(chart):
post_process=post_process,
)

# Note: It is advised to switch the pages after pausing the model
# on the Solara dashboard.
page = SolaraViz(
model,
renderer,
components=[
make_plot_component("#Traders"),
make_plot_component("Price"),
make_plot_component("#Traders", page=1),
make_plot_component("Price", page=1),
],
model_params=model_params,
name="Sugarscape {G1, M, T}",
Expand Down
12 changes: 9 additions & 3 deletions mesa/visualization/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ def make_plot_component(
measure: str | dict[str, str] | list[str] | tuple[str],
post_process: Callable | None = None,
backend: str = "matplotlib",
page: int = 0,
**plot_drawing_kwargs,
):
"""Create a plotting function for a specified measure using the specified backend.
Expand All @@ -82,15 +83,20 @@ def make_plot_component(
measure (str | dict[str, str] | list[str] | tuple[str]): Measure(s) to plot.
post_process: a user-specified callable to do post-processing called with the Axes instance.
backend: the backend to use {"matplotlib", "altair"}
page: Page number where the plot should be displayed (default 0).
plot_drawing_kwargs: additional keyword arguments to pass onto the backend specific function for making a plotting component

Returns:
function: A function that creates a plot component
(function, page): A tuple of a function and page number that creates a plot component on that specific page.
"""
if backend == "matplotlib":
return make_mpl_plot_component(measure, post_process, **plot_drawing_kwargs)
return make_mpl_plot_component(
measure, post_process, page, **plot_drawing_kwargs
)
elif backend == "altair":
return make_altair_plot_component(measure, post_process, **plot_drawing_kwargs)
return make_altair_plot_component(
measure, post_process, page, **plot_drawing_kwargs
)
else:
raise ValueError(
f"unknown backend {backend}, must be one of matplotlib, altair"
Expand Down
6 changes: 4 additions & 2 deletions mesa/visualization/components/altair_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,23 +454,25 @@ def apply_rgba(val, vmin=vmin, vmax=vmax, alpha=alpha, portrayal=portrayal):
def make_altair_plot_component(
measure: str | dict[str, str] | list[str] | tuple[str],
post_process: Callable | None = None,
page: int = 0,
grid=False,
):
"""Create a plotting function for a specified measure.

Args:
measure (str | dict[str, str] | list[str] | tuple[str]): Measure(s) to plot.
post_process: a user-specified callable to do post-processing called with the Axes instance.
page: Page number where the plot should be displayed.
grid: Bool to draw grid or not.

Returns:
function: A function that creates a PlotAltair component.
(function, page): A tuple of a function that creates a PlotAltair component and a page number.
"""

def MakePlotAltair(model):
return PlotAltair(model, measure, post_process=post_process, grid=grid)

return MakePlotAltair
return (MakePlotAltair, page)


@solara.component
Expand Down
6 changes: 4 additions & 2 deletions mesa/visualization/components/matplotlib_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,25 +107,27 @@ def make_plot_measure(*args, **kwargs): # noqa: D103
def make_mpl_plot_component(
measure: str | dict[str, str] | list[str] | tuple[str],
post_process: Callable | None = None,
page: int = 0,
save_format="png",
):
"""Create a plotting function for a specified measure.

Args:
measure (str | dict[str, str] | list[str] | tuple[str]): Measure(s) to plot.
post_process: a user-specified callable to do post-processing called with the Axes instance.
page: Page number where the plot should be displayed.
save_format: save format of figure in solara backend

Returns:
function: A function that creates a PlotMatplotlib component.
(function, page): A tuple of a function that creates a PlotMatplotlib component and a page number.
"""

def MakePlotMatplotlib(model):
return PlotMatplotlib(
model, measure, post_process=post_process, save_format=save_format
)

return MakePlotMatplotlib
return (MakePlotMatplotlib, page)


@solara.component
Expand Down
Loading
Loading