mesa icon indicating copy to clipboard operation
mesa copied to clipboard

Allow PropertyLayerStyle instance in draw_propertylayer

Open ShreyasN707 opened this issue 2 weeks ago β€’ 5 comments

Summary

This PR improves the PropertyLayer visualization API by allowing users to pass a PropertyLayerStyle instance directly to draw_propertylayer. This removes the need to wrap the style in a function for simple, uniform styling cases.

issue #2923

Background / Problem

Previously, even the simplest styling required a callable, like:

def propertylayer_portrayal(layer): return PropertyLayerStyle(colormap="viridis", colorbar=True)

For cases where the style is the same across all layers, this wrapper didn't add any value and made the API feel unnecessarily verbose. This PR addresses feedback suggesting the API should accept both:

  • a direct PropertyLayerStyle instance (for uniform styling)

  • a callable (for conditional or per-layer styling)

This makes the API more intuitive and aligns with common Python patterns.

Implementation

Changes in mesa/visualization/space_renderer.py:

  • Updated draw_propertylayer to detect when propertylayer_portrayal is a PropertyLayerStyle instance.

  • When an instance is provided, it's automatically wrapped in a small lambda so the existing backend logic continues to work without modification.

  • Updated type hints to reflect that the argument may now be either a callable or a style instance.

Testing

  • Added a dedicated test case: test_property_layer_style_instance in tests/test_space_renderer.py to confirm that passing a PropertyLayerStyle instance works correctly.

  • Ran the existing test suite (pytest tests/test_space_renderer.py) to ensure no regressions β€” all 16 tests passed.

Additional Notes

This change reduces boilerplate for the common simple-use scenario while still supporting the more flexible function-based approach for complex styling. It should make the API easier and more pleasant to use without breaking any existing behavior.

ShreyasN707 avatar Dec 08 '25 18:12 ShreyasN707

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small πŸ”΅ -0.5% [-1.1%, +0.1%] πŸ”΅ -1.5% [-1.7%, -1.4%]
BoltzmannWealth large πŸ”΅ -1.3% [-17.5%, +17.1%] πŸ”΅ -1.3% [-2.6%, -0.1%]
Schelling small πŸ”΅ -0.2% [-0.3%, -0.0%] πŸ”΅ -1.2% [-1.4%, -1.1%]
Schelling large πŸ”΅ -0.2% [-17.5%, +21.6%] πŸ”΅ +12.1% [-3.3%, +37.5%]
WolfSheep small πŸ”΅ -0.6% [-0.9%, -0.3%] πŸ”΅ +0.1% [-0.1%, +0.3%]
WolfSheep large πŸ”΅ -17.1% [-40.4%, -0.7%] πŸ”΅ +10.2% [-12.5%, +38.6%]
BoidFlockers small πŸ”΅ -0.7% [-1.6%, +0.1%] πŸ”΅ -0.8% [-1.0%, -0.6%]
BoidFlockers large πŸ”΅ -0.4% [-1.0%, +0.2%] πŸ”΅ -0.4% [-0.6%, -0.3%]

github-actions[bot] avatar Dec 08 '25 18:12 github-actions[bot]

@EwoutH Please review my PR.

ShreyasN707 avatar Dec 08 '25 19:12 ShreyasN707

@ShreyasN707 Thanks for this PR! The changes are good and clean, but this PR interferes with #2893 and I personally would like this feature in our new API so in my opinion it's best for #2893 to be merged first, what do you say @EwoutH?

Sahil-Chhoker avatar Dec 09 '25 04:12 Sahil-Chhoker

Yes, very fair, let’s get #2893 in first.

EwoutH avatar Dec 09 '25 04:12 EwoutH

@Sahil-Chhoker Sounds good to me! Let’s get #2893 merged first. Once that’s in, I’ll rebase this PR and fix up anything that needs adjusting.

ShreyasN707 avatar Dec 09 '25 18:12 ShreyasN707

@ShreyasN707 sorry for the delay, #2893 is merged now so can you update this PR accordingly.

Sahil-Chhoker avatar Dec 16 '25 06:12 Sahil-Chhoker

@ShreyasN707 sorry for the delay, #2893 is merged now so can you update this PR accordingly.

@Sahil-Chhoker sure! Will do it by EOD.

ShreyasN707 avatar Dec 16 '25 08:12 ShreyasN707

@Sahil-Chhoker @EwoutH Please review the changes.

ShreyasN707 avatar Dec 16 '25 14:12 ShreyasN707