Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@falloficarus22
Copy link
Contributor

@falloficarus22 falloficarus22 commented Dec 16, 2025

Summary

This PR enables users to control whether markers in the Altair and Matplotlib visualization backends (both legacy and new) are "filled" or "outlined" via the AgentPortrayalStyle. This resolves an existing FIXME in the codebase and ensures visual consistency across all Mesa visualization components.
Reference: Closes #2956

Motive

Previously, visualization backends often hardcoded the filled status of markers to True, which limited customization. Users who wanted outline-only shapes (e.g., empty circles or squares) were unable to achieve this without low-level hacks.
This change exposes the filled attribute in AgentPortrayalStyle, giving users direct control over this visual property across all four visualization backends, ensuring feature parity as requested.

Implementation

  • Updated AgentPortrayalStyle: Added a filled: bool | None = True field to the dataclass in mesa/visualization/components/portrayal_components.py. It defaults to True to maintain backward compatibility.
  • Applied changes across all 4 visualization backends:
    • New Altair Backend: Modified mesa/visualization/backends/altair_backend.py to read the filled attribute and use it in Altair chart encoding.
    • Legacy Altair Backend: Updated mesa/visualization/components/altair_components.py to support AgentPortrayalStyle and respect the filled status in Solara-based Altair visualizations.
    • New Matplotlib Backend: Modified mesa/visualization/backends/matplotlib_backend.py to support the filled attribute.
    • Legacy Matplotlib Backend: Modified mesa/visualization/mpl_space_drawing.py to respect the filled attribute.
  • Logic: When filled=False, the backends set the marker's face color to "none" (transparent) and ensure the edge color is visible, mimicking a hollow marker.
  • Backward Compatibility: Added logic across all backends to check for a "filled" key in deprecated dictionary-based portrayals.
  • Added Tests:
    • test_altair_backend_collects_filled_attribute in tests/test_backends.py to verify Altair collection.
    • test_matplotlib_backend_collects_filled_attribute in tests/test_backends.py to verify color translation to "none" in Matplotlib.

Usage Examples

New Portrayal Style (Hollow Markers):

def agent_portrayal(agent):
    return AgentPortrayalStyle(
        marker="o",
        color="red",
        filled=False  # New: Creates a hollow/outlined red circle
    )

Portrayal Style with Default (Backward Compatible):

def agent_portrayal(agent):
    return AgentPortrayalStyle(
        marker="o",
        color="blue"
        # filled defaults to True, creating a solid blue circle
    )

Before
image
After
image

Additional Notes

  • This change is fully backward compatible; existing models will continue to render filled markers by default.
  • The implementation addresses the FIXME: Make filled user-controllable comment found in the backends.
  • Ensures full feature parity between all Altair and Matplotlib visualization backends (legacy and new) as requested during review.

falloficarus22 and others added 2 commits December 16, 2025 05:24
Enable users to specify whether agent markers should be filled or outlined in the Altair visualization backend. This addresses an existing FIXME in the code where markers were hardcoded to be filled.

Changes:
- Add [filled](cci:1://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:356:4-359:9) field to [AgentPortrayalStyle](cci:2://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/components/portrayal_components.py:18:0-82:66) (defaults to True).
- Update [AltairBackend](cci:2://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/backends/altair_backend.py:30:0-445:19) to use the [filled](cci:1://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:356:4-359:9) value from the portrayal.
- Add regression test to verify [filled](cci:1://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:356:4-359:9) attribute collection.
@github-actions
Copy link

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔴 +4.3% [+3.2%, +5.2%] 🔵 +1.7% [+1.6%, +1.8%]
BoltzmannWealth large 🔴 +4.4% [+3.7%, +5.1%] 🔴 +11.3% [+7.2%, +15.3%]
Schelling small 🔵 +1.3% [+0.3%, +2.4%] 🔵 +0.7% [+0.0%, +1.3%]
Schelling large 🔵 -0.3% [-0.7%, +0.1%] 🔵 -0.5% [-2.3%, +1.0%]
WolfSheep small 🔵 -1.0% [-2.4%, +0.2%] 🔵 -0.1% [-0.3%, +0.2%]
WolfSheep large 🔵 +1.4% [-1.1%, +5.4%] 🔵 -0.9% [-2.9%, +0.9%]
BoidFlockers small 🔵 +0.2% [-0.2%, +0.6%] 🔵 -0.1% [-0.3%, +0.1%]
BoidFlockers large 🔵 +1.3% [+0.8%, +1.8%] 🔵 -0.6% [-1.1%, -0.2%]

@Sahil-Chhoker
Copy link
Collaborator

Thanks @falloficarus22 for this PR, user control was indeed necessary here, but what's the behavior of these changes on the matplotlib backend, because if possible I’d like both backends to function similarly.

@falloficarus22
Copy link
Contributor Author

Thanks @falloficarus22 for this PR, user control was indeed necessary here, but what's the behavior of these changes on the matplotlib backend, because if possible I’d like both backends to function similarly.

Currently, these changes do not affect the Matplotlib backend; it simply ignores the new filled attribute and continues to render filled markers by default.

Do you think any changes are needed?

@Sahil-Chhoker
Copy link
Collaborator

Do you think any changes are needed?

As I said, I want both the backends to behave similarly, so if you could also apply the same behavior to the matplotlib agents it would be helpful.

@falloficarus22
Copy link
Contributor Author

Do you think any changes are needed?

As I said, I want both the backends to behave similarly, so if you could also apply the same behavior to the matplotlib agents it would be helpful.

Okay, I'll work on it

falloficarus22 and others added 2 commits December 16, 2025 08:46
- Updated [collect_agent_data](cci:1://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/mpl_space_drawing.py:51:0-191:15) in [mpl_space_drawing.py](cci:7://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/mpl_space_drawing.py:0:0-0:0) to respect the [filled](cci:1://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:356:4-359:9) attribute from [AgentPortrayalStyle](cci:2://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/components/portrayal_components.py:18:0-82:66).
- Logic added to set  and ensure  are set when , producing hollow markers consistent with the Altair backend.
@falloficarus22
Copy link
Contributor Author

@Sahil-Chhoker review

@Sahil-Chhoker
Copy link
Collaborator

@falloficarus22 We currently maintain four visualization backends: two legacy ones: mpl_space_drawing for Matplotlib and altair_components for Altair and two newer backends located in the backend directory of the visualization module. Please apply the required changes across all of these files. I’ll review the PR once it’s ready.

@falloficarus22
Copy link
Contributor Author

@falloficarus22 We currently maintain four visualization backends: two legacy ones: mpl_space_drawing for Matplotlib and altair_components for Altair and two newer backends located in the backend directory of the visualization module. Please apply the required changes across all of these files. I’ll review the PR once it’s ready.

okay

Implement [filled](cci:1://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:358:4-359:47) attribute handling in the newer Matplotlib backend
and legacy Altair components. This ensures feature parity across all
four visualization backends as requested by reviewers.
When  is specified in [AgentPortrayalStyle](cci:2://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/components/portrayal_components.py:18:0-82:66), markers
render with a transparent face color and visible edge colors. This
behavior is now consistent across the newer backends and legacy
components.
Specifically:
- Update [MatplotlibBackend](cci:2://file://wsl.localhost/Ubuntu/root/mesa/mesa/visualization/backends/matplotlib_backend.py:34:0-437:28) and legacy Altair logic for markers.
- Add unit tests in [test_backends.py](cci:7://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:0:0-0:0) for Matplotlib collection.
- Fix boolean comparison lint errors (E712) for Ruff compliance.
- Maintain backward compatibility by defaulting [filled](cci:1://file://wsl.localhost/Ubuntu/root/mesa/tests/test_backends.py:358:4-359:47) to True.
@falloficarus22
Copy link
Contributor Author

@Sahil-Chhoker check now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow "Filled" Markers in Altair Backend (FIXME)

3 participants