Skip to content

Added AgentPortrayalStyle and PropertyLayerStyle #2786

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

Merged
merged 22 commits into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6e6f2b4
added AgentPortrayalStyle and PropertyLayerStyle
Sahil-Chhoker May 19, 2025
8b2535b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 19, 2025
8870139
added docstrings
Sahil-Chhoker May 19, 2025
82d690b
added precommit suggestions
Sahil-Chhoker May 19, 2025
54b706c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 19, 2025
4723c39
name update
Sahil-Chhoker May 19, 2025
b852f5b
Merge branch 'portrayal-components' of https://github.com/Sahil-Chhok…
Sahil-Chhoker May 19, 2025
490e751
added coderabbit review
Sahil-Chhoker May 20, 2025
eee4d60
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 20, 2025
d0178ac
Merge branch 'main' into portrayal-components
Sahil-Chhoker May 21, 2025
5fa873f
Merge branch 'main' into portrayal-components
Sahil-Chhoker May 23, 2025
c91d4c4
added usage example and fix __init__ file
Sahil-Chhoker May 23, 2025
fd41bc1
added backwards compatability for dict propertylayer_portrayal
Sahil-Chhoker May 23, 2025
94b7d2d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 23, 2025
9a0019b
fix the network logic
Sahil-Chhoker May 24, 2025
a76ba8e
null check for agnet pos
Sahil-Chhoker May 24, 2025
56e3baf
added tests
Sahil-Chhoker May 25, 2025
88be455
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 25, 2025
c04aef6
added docstrings
Sahil-Chhoker May 25, 2025
91a1990
resolve conflicts
Sahil-Chhoker May 25, 2025
9cf5b36
added precommit suggestions
Sahil-Chhoker May 25, 2025
a21b467
delete unwanted test
Sahil-Chhoker May 25, 2025
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
20 changes: 15 additions & 5 deletions mesa/examples/advanced/sugarscape_g1mt/app.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
from mesa.examples.advanced.sugarscape_g1mt.model import SugarscapeG1mt
from mesa.visualization import Slider, SolaraViz, make_plot_component
from mesa.visualization.components import AgentPortrayalStyle, PropertyLayerStyle
from mesa.visualization.components.matplotlib_components import make_mpl_space_component


def agent_portrayal(agent):
return {"marker": "o", "color": "red", "size": 10}
return AgentPortrayalStyle(

Check warning on line 8 in mesa/examples/advanced/sugarscape_g1mt/app.py

View check run for this annotation

Codecov / codecov/patch

mesa/examples/advanced/sugarscape_g1mt/app.py#L8

Added line #L8 was not covered by tests
x=agent.cell.coordinate[0],
y=agent.cell.coordinate[1],
color="red",
marker="o",
size=10,
zorder=1,
)


propertylayer_portrayal = {
"sugar": {"color": "blue", "alpha": 0.8, "colorbar": True, "vmin": 0, "vmax": 10},
"spice": {"color": "red", "alpha": 0.8, "colorbar": True, "vmin": 0, "vmax": 10},
}
def propertylayer_portrayal(layer):
if layer.name == "sugar":
return PropertyLayerStyle(

Check warning on line 20 in mesa/examples/advanced/sugarscape_g1mt/app.py

View check run for this annotation

Codecov / codecov/patch

mesa/examples/advanced/sugarscape_g1mt/app.py#L20

Added line #L20 was not covered by tests
color="blue", alpha=0.8, colorbar=True, vmin=0, vmax=10
)
return PropertyLayerStyle(color="red", alpha=0.8, colorbar=True, vmin=0, vmax=10)

Check warning on line 23 in mesa/examples/advanced/sugarscape_g1mt/app.py

View check run for this annotation

Codecov / codecov/patch

mesa/examples/advanced/sugarscape_g1mt/app.py#L23

Added line #L23 was not covered by tests


sugarscape_space = make_mpl_space_component(
Expand Down
69 changes: 0 additions & 69 deletions mesa/examples/advanced/sugarscape_g1mt/tests.py

This file was deleted.

15 changes: 14 additions & 1 deletion mesa/visualization/components/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""custom solara components."""
"""Custom visualization components."""

from __future__ import annotations

Expand All @@ -10,6 +10,19 @@
make_mpl_plot_component,
make_mpl_space_component,
)
from .portrayal_components import AgentPortrayalStyle, PropertyLayerStyle

__all__ = [
"AgentPortrayalStyle",
"PropertyLayerStyle",
"SpaceAltair",
"SpaceMatplotlib",
"make_altair_space",
"make_mpl_plot_component",
"make_mpl_space_component",
"make_plot_component",
"make_space_component",
]


def make_space_component(
Expand Down
79 changes: 79 additions & 0 deletions mesa/visualization/components/portrayal_components.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""Portrayal Components Module.

This module defines data structures for styling visual elements in Mesa agent-based model visualizations.
It provides user-facing classes to specify how agents and property layers should appear in the rendered space.

Classes:
- AgentPortrayalStyle: Controls the appearance of individual agents (e.g., color, shape, size, etc.).
- PropertyLayerStyle: Controls the appearance of background property layers (e.g., color gradients or uniform fills).

These components are designed to be passed into Mesa visualizations to customize and standardize how data is presented.
"""

from dataclasses import dataclass
from typing import Any


@dataclass
class AgentPortrayalStyle:
"""Represents the visual styling options for an agent in a visualization.

User facing component to control how agents are drawn.
Allows specifying properties like color, size,
marker shape, position, and other plot attributes.
"""

x: float | None = None
y: float | None = None
color: str | tuple | None = "tab:blue"
marker: str | None = "o"
size: int | float | None = 50
zorder: int | None = 1
alpha: float | None = 1.0
edgecolors: str | tuple | None = None
linewidths: float | int | None = 1.0

def update(self, *updates_fields: tuple[str, Any]):
"""Updates attributes from variable (field_name, new_value) tuple arguments.

Example:
>>> def agent_portrayal(agent):
>>> primary_style = AgentPortrayalStyle(color="blue", marker="^", size=10, x=agent.pos[0], y=agent.pos[1])
>>> if agent.type == 1:
>>> primary_style.update(("color", "red"), ("size", 30))
>>> return primary_style
"""
for field_to_change, field_to_change_to in updates_fields:
if hasattr(self, field_to_change):
setattr(self, field_to_change, field_to_change_to)
else:
raise AttributeError(
f"'{type(self).__name__}' object has no attribute '{field_to_change}'"
)


@dataclass
class PropertyLayerStyle:
"""Represents the visual styling options for a property layer in a visualization.

User facing component to control how property layers are drawn.
Allows specifying properties like colormap, single color, value limits,
and colorbar visibility.

Note: You can specify either a 'colormap' (for varying data) or a single
'color' (for a uniform layer appearance), but not both simultaneously.
"""

colormap: str | None = None
color: str | None = None
alpha: float = 0.8
colorbar: bool = True
vmin: float | None = None
vmax: float | None = None

def __post_init__(self):
"""Validate that color and colormap are not simultaneously specified."""
if self.color is not None and self.colormap is not None:
raise ValueError("Specify either 'color' or 'colormap', not both.")
if self.color is None and self.colormap is None:
raise ValueError("Specify one of 'color' or 'colormap'")
Loading