Skip to content

Conversation

@flucco
Copy link

@flucco flucco commented Oct 28, 2025

Summary

Fix a visualization error for PropertyLayers on HexGrids where color values were displayed in the wrong places. Add a transpose operation to put the color values in the right order.

Bug / Issue

Issue 2859. I found that when trying to display PropertyLayers on Hexagonal Grids, color values are consistently shown in the wrong places on the grid. The visualizations for hexagonal grids look dramatically different from the visualizations for orthogonal grids. You would expect the visualizations to look similar besides the small differences caused by the hexagonal cell layout.

Implementation

The issue was in the draw_propertylayer function in matplotlib_backend.py. The code for the HexGrid visualization flattened the W x H PropertyLayer data into a 1D array, then matched those values to a collection of hexagonal grid cells arranged in H x W order. The different orders led to incorrect placement of values on the grid.

The one-line fix is to add a transpose operation (.T) before the ravel operation that flattens the data. This creates a 1D array of color values in the correct H x W order. I picked this approach because it's simple and matches the implementation used for orthogonal grids. Now, all cases use a simple transpose operation to adjust the data for graphing purposes.

Testing

I tested this fix in a modified version of the Sugarscape example, described in the issue and available in [this branch] (https://github.com/flucco/mesa/tree/bug_example) of my fork. I used the original sugarscape map, 50x50 modifications of that map which added asymmetrical elements, and modified maps that had varied W x H ratios.

Before the fix, the values aren’t shown in the right places on the grid. Agents should be in white squares due to consumption of resources, but the white squares appear in other locations. Here is the comparison at timestep 1 of Orthogonal and Hexagonal behaviors using the 60x40 grid. (Note: I changed the size of the agents to 7 and alpha to 0.8 as it's easier to see the color values). See also the examples shown in the issue.

Orthogonal:

ovn_step1_60_40

Hexagonal:

hex_step1_60_40

Note the incorrect placement of the color values, as shown by the differences from the orthogonal grid and how the agents are not in white squares. Instead, the white squares that should correspond to the agents appear elsewhere in the grid.

After the fix, the behavior is correct in all cases I tested, and closely resembles the visualization of the original orthogonal model.

Hexagonal after fix:

hex_step1_60_40_FIXED

I tested the fixed code on all the basic tests given and ran the formatting checks just to make sure.

Additional Notes

  • I admittedly didn’t do much additional testing because the change is extremely minimal, adding only a single operation in a single line of code. I believe it should only affect the precise thing I was looking to fix. Please let me know if there's anything else it would make sense to test.

  • I deleted my pull request and redid it because I didn't have the updated examples in my main branch. I wasn't sure if I should keep them in there but they're very easy to take out. All the examples are in the sugarscape_hex folder. The only actual change is to matplotlib_backend.py. (Also, I initially changed mpl_space_drawing.py, but that code is correct and shouldn't have been modified, so I changed it back).

@flucco flucco changed the title Fix hexgrid Fix PropertyLayer Visualization on HexGrids Oct 28, 2025
@github-actions
Copy link

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 +0.5% [-0.2%, +1.1%] 🔵 -0.6% [-0.8%, -0.4%]
BoltzmannWealth large 🔵 -0.1% [-0.7%, +0.4%] 🔵 +0.7% [+0.3%, +1.3%]
Schelling small 🔵 -0.1% [-0.3%, -0.0%] 🔵 -0.4% [-0.6%, -0.2%]
Schelling large 🔵 -0.2% [-0.5%, +0.2%] 🔵 +0.3% [+0.1%, +0.5%]
WolfSheep small 🔵 +0.4% [+0.1%, +0.6%] 🔵 -0.3% [-0.5%, -0.2%]
WolfSheep large 🔵 +0.4% [-0.1%, +0.8%] 🔵 +0.6% [+0.1%, +1.1%]
BoidFlockers small 🔵 +0.4% [-0.2%, +1.0%] 🔵 +1.8% [+1.6%, +2.0%]
BoidFlockers large 🔵 +0.1% [-0.3%, +0.5%] 🔵 +1.8% [+1.4%, +2.1%]

@flucco flucco marked this pull request as draft October 28, 2025 01:06
@flucco flucco marked this pull request as ready for review October 28, 2025 01:15
@github-actions
Copy link

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔴 +4.5% [+3.3%, +5.7%] 🔵 +0.6% [+0.3%, +0.8%]
BoltzmannWealth large 🔵 -1.0% [-1.8%, -0.1%] 🔵 -0.2% [-2.6%, +3.6%]
Schelling small 🔵 -0.1% [-0.3%, +0.1%] 🔵 -0.1% [-0.3%, +0.1%]
Schelling large 🔵 +0.1% [-0.5%, +0.7%] 🔵 -0.0% [-1.2%, +1.1%]
WolfSheep small 🔵 +0.4% [+0.1%, +0.7%] 🔴 +3.3% [+3.1%, +3.6%]
WolfSheep large 🔵 +1.0% [-0.2%, +2.6%] 🔵 +2.0% [+0.3%, +4.1%]
BoidFlockers small 🔵 +0.1% [-0.6%, +0.7%] 🔵 +0.1% [-0.0%, +0.3%]
BoidFlockers large 🔵 +0.9% [+0.3%, +1.5%] 🔵 +0.0% [-0.2%, +0.2%]

@Sahil-Chhoker
Copy link
Collaborator

Thanks for the detailed explanation and for fixing the issue. You’re right — the data was mapped incorrectly, and transposing it does indeed fix the problem, so this PR looks good to me. I also tried running your example but couldn’t get it to work in Altair — not sure why.

You can go ahead and remove the example and the related files from this PR now.

@EwoutH EwoutH added bug Release notes label visualisation labels Oct 28, 2025
@EwoutH
Copy link
Member

EwoutH commented Oct 28, 2025

Thanks for the detailed bug report (#2859) and PR @flucco!

@Sahil-Chhoker thanks for picking up the review.

@quaquel you might also find this interesting and want to skim this through.

@quaquel
Copy link
Member

quaquel commented Oct 28, 2025

I agree with @Sahil-Chhoker, the transpose is the right fix. However, all the other changes seem not to be relevant so once those are removed this can be merged.

@flucco
Copy link
Author

flucco commented Oct 28, 2025

Thanks for the detailed explanation and for fixing the issue. You’re right — the data was mapped incorrectly, and transposing it does indeed fix the problem, so this PR looks good to me. I also tried running your example but couldn’t get it to work in Altair — not sure why.

You can go ahead and remove the example and the related files from this PR now.

Thank you! I will remove my example folder from the PR. It's still in my bug_example branch for anyone's future reference.

RE Altair, the example I made only works with Solara on the Matplotlib backend. I only ever used the Matplotlib code in my own project, so that was the only bug I found. After looking at the Altair version myself, I think there is a separate issue with the Altair visualizations in the latest version of the code. I haven't dug into it much but if you run the unmodified Sugarscape example with the current code, you'll see a bug that looks very similar to what I described and fixed here. So either there's a similar problem in the Altair code or the example itself needs modification to work with the latest updates.

@EwoutH
Copy link
Member

EwoutH commented Oct 28, 2025

@flucco feel free to open a new PR if that's easier! Whatever works for you

@quaquel
Copy link
Member

quaquel commented Oct 28, 2025

So either there's a similar problem in the Altair code or the example itself needs modification to work with the latest updates.

I would not be surprised if an identical issue exists in altair. This transpose stuff has tricked me up several times before with property layer visualization.

@flucco flucco closed this Oct 29, 2025
@Sahil-Chhoker
Copy link
Collaborator

I also dug around a bit, the property layer data mapping for altair and matplotlib is also flipped.

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

Labels

bug Release notes label visualisation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants