Skip to content

Fix #2904: Use PropertyLayerStyle instead of dict for property layers#2912

Closed
Tejasv-Singh wants to merge 3 commits intomesa:mainfrom
Tejasv-Singh:fix-issue-2904-property-layer
Closed

Fix #2904: Use PropertyLayerStyle instead of dict for property layers#2912
Tejasv-Singh wants to merge 3 commits intomesa:mainfrom
Tejasv-Singh:fix-issue-2904-property-layer

Conversation

@Tejasv-Singh
Copy link
Copy Markdown
Contributor

Update Property Layer Portrayals to PropertyLayerStyle (Part of #2904)

This PR updates property layer portrayals in tests/test_components_matplotlib.py to use PropertyLayerStyle instead of deprecated dict-based portrayals. This removes related deprecation warnings and aligns the tests with the current visualization API.

Linked Issue

Closes #2904.

Summary of Changes

Added import for PropertyLayerStyle:

from mesa.visualization.components import PropertyLayerStyle

Refactored test_draw_property_layers to use a callable portrayal function rather than a dict.

Before
draw_property_layers(grid, {"test": {"colormap": "viridis", "colorbar": True}}, ax)

After

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

draw_property_layers(grid, propertylayer_portrayal, ax)

No changes required in library code (mpl_space_drawing.py, altair_backend.py) since they already support PropertyLayerStyle.

Testing
Targeted test
pytest tests/test_components_matplotlib.py::test_draw_property_layers -v

Result: Passes; deprecation warnings resolved.

Full test file
pytest tests/test_components_matplotlib.py -v

Result: All 7 tests pass with no property layer portrayal warnings.

Notes

This PR updates only the tests as part of the incremental migration plan in #2904.

The core visualization pipeline already supports PropertyLayerStyle; this change ensures the tests reflect the modern API.

This resolves item 1.2 from issue #2904.``

@github-actions
Copy link
Copy Markdown

github-actions bot commented Dec 2, 2025

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 -0.5% [-1.0%, -0.0%] 🔵 +2.1% [+1.9%, +2.2%]
BoltzmannWealth large 🔵 -0.2% [-1.0%, +0.4%] 🔵 +1.7% [+0.8%, +3.0%]
Schelling small 🔵 -1.1% [-1.4%, -0.8%] 🔵 -3.3% [-4.3%, -2.2%]
Schelling large 🔵 -0.2% [-0.7%, +0.3%] 🔵 -1.9% [-5.0%, +0.8%]
WolfSheep small 🔵 -1.9% [-2.4%, -1.4%] 🔵 -1.4% [-1.7%, -1.1%]
WolfSheep large 🔵 -1.3% [-1.8%, -0.7%] 🔵 -1.0% [-1.8%, -0.3%]
BoidFlockers small 🔵 -2.6% [-3.4%, -1.9%] 🔵 -1.8% [-2.1%, -1.5%]
BoidFlockers large 🔵 -2.1% [-2.9%, -0.9%] 🔵 -2.2% [-2.4%, -1.9%]

Comment on lines +228 to +229
def propertylayer_portrayal(layer):
return PropertyLayerStyle(colormap="viridis", colorbar=True)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function takes layer as input, but doesn't use it. Can you explain why?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sahil-Chhoker do you know how this works?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EwoutH Sorry for the late reply, I was working on fixing the merge conflicts.

To answer your question: I kept the test simple because I just wanted to verify that the renderer accepts the new PropertyLayerStyle class, so inspecting the specific layer logic wasn't necessary for this fixture.

I have opened a fresh PR here: #2920 to handle the merge conflicts cleanly. In that new PR, I renamed the argument to _ as suggested to indicate it is unused. Was facing merge conflicts there as well. I will try to fix that as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sahil-Chhoker do you know how this works?

Yeah, the property layer portrayal behaves exactly like agent portrayal, it taken in a layer and calls the portrayal function on every layer and you can pass different portrayals for different layers, in this case all layers are called with only one portrayal function.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Sahil-Chhoker for the explanation, I understand it now. The layer parameter enables conditional styling based on layer properties (name, data values, etc.), similar to how agent portrayal works. For this test, it's simply verifying that the renderer accepts PropertyLayerStyle objects, so the parameter isn't needed.

This PR is good to merge as-is.


However, I'm wondering if we should consider improving this API in a follow-up. The current design feels a bit awkward:

  • Simple cases require writing a function wrapper that always returns the same object
  • The function --> class pattern isn't the most intuitive

Right now users must write:

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

Where the function wrapper adds no value when the style is uniform across all layers.

What if we allowed the visualization to accept either:

  1. A PropertyLayerStyle instance directly (for simple uniform styling)
  2. A callable function (for conditional/per-layer styling)

Similar to how Python's sorted() accepts both key=str.lower and key=lambda x: complex_logic(x).

Not urgent at all, but might be worth following up on.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @EwoutH for the detailed write-up, I also think the API can be improved and your approach is pretty good, but currently I'm a little busy with my exams, I'll be able to take a careful look by the end of this month.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, split it off in a new issue: #2923

@EwoutH
Copy link
Copy Markdown
Member

EwoutH commented Dec 4, 2025

Closing this PR in favor of #2920.

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.

Tracking issue: Resolve test suite warnings

4 participants