Refactor SpaceRenderer API to separate setup and draw methods#2893
Refactor SpaceRenderer API to separate setup and draw methods#2893Sahil-Chhoker merged 30 commits intomesa:mainfrom
Conversation
|
@coderabbitai full review |
✅ Actions performedFull review triggered. |
WalkthroughThe visualization API was refactored to a stateful, chainable setup/draw pattern: SpaceRenderer now stores portrayals and draw kwargs via setup_* methods and executes drawings without per-call kwargs. Space drawer parameter names were standardized (space/ chart kwargs renamed), and Solara integration now calls draw_* without forwarding kwargs. Changes
Sequence Diagram(s)sequenceDiagram
participant Page as Solara Viz
participant Renderer as SpaceRenderer
participant Drawer as Space Drawer
Note over Page,Renderer: New stateful, chainable flow
Page->>Renderer: setup_structure(**draw_space_kwargs)
Renderer-->>Page: self
Page->>Renderer: setup_agents(agent_portrayal, **draw_agent_kwargs)
Renderer-->>Page: self
Page->>Renderer: setup_propertylayer(propertylayer_portrayal)
Renderer-->>Page: self
Page->>Renderer: render()
Note right of Renderer: Uses stored state
Renderer->>Drawer: draw_matplotlib() / draw_altair()
Drawer-->>Renderer: rendered output
Renderer-->>Page: visualization
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
mesa/visualization/space_renderer.py (1)
350-361: Critical bug: References to non-existent attributes.Lines 355 and 357 reference
self.space_kwargsandself.agent_kwargs, but these attributes don't exist. The correct names areself.draw_space_kwargsandself.draw_agent_kwargs.Apply this diff to fix the bug:
if self.space_mesh: - structure = self.draw_structure(**self.space_kwargs) + structure = self.draw_structure() if self.agent_mesh: - agents = self.draw_agents(self.agent_portrayal, **self.agent_kwargs) + agents = self.draw_agents() if self.propertylayer_mesh: - prop_base, prop_cbar = self.draw_propertylayer( - self.propertylayer_portrayal - ) + prop_base, prop_cbar = self.draw_propertylayer()
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
mesa/visualization/solara_viz.py(2 hunks)mesa/visualization/space_drawers.py(21 hunks)mesa/visualization/space_renderer.py(5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Sahil-Chhoker
Repo: projectmesa/mesa PR: 2803
File: mesa/visualization/backends/altair_backend.py:312-553
Timestamp: 2025-06-20T16:44:20.677Z
Learning: In mesa/visualization/backends/altair_backend.py, the author prefers to keep the draw_propertylayer method intact despite its complexity, as they believe breaking it into smaller functions would divert attention from the main logic flow. The method is well-documented and follows a clear sequence of operations for property layer rendering.
📚 Learning: 2025-06-20T16:44:20.677Z
Learnt from: Sahil-Chhoker
Repo: projectmesa/mesa PR: 2803
File: mesa/visualization/backends/altair_backend.py:312-553
Timestamp: 2025-06-20T16:44:20.677Z
Learning: In mesa/visualization/backends/altair_backend.py, the author prefers to keep the draw_propertylayer method intact despite its complexity, as they believe breaking it into smaller functions would divert attention from the main logic flow. The method is well-documented and follows a clear sequence of operations for property layer rendering.
Applied to files:
mesa/visualization/space_renderer.pymesa/visualization/solara_viz.pymesa/visualization/space_drawers.py
🪛 GitHub Actions: build
mesa/visualization/space_renderer.py
[error] 1-1: SpaceRenderer API mismatch: draw_structure() does not accept grid_color as a keyword, causing failures in Boltzmann model visualization tests.
[error] 1-1: SpaceRenderer API mismatch: draw_agents() does not accept agent_portrayal as a keyword, causing failures in Conways and EpStein visualization tests.
[error] 1-1: SpaceRenderer API mismatch: render() does not accept agent_portrayal as a keyword, causing failures in Schelling, Boid Flockers, and Sugarscape tests.
[error] 1-1: SpaceRenderer API mismatch: draw_structure() does not accept node_kwargs as a keyword, causing failures in Virus on Network visualization.
[error] 1-1: SpaceRenderer API mismatch: draw_agents() does not accept agent_portrayal as a keyword, causing failures in EpStein Civil Violence and Wolf-Sheep tests.
[error] 1-1: SpaceRenderer API mismatch: draw_propertylayer() is invoked with a positional argument in tests, but the method signature does not expect it, causing failure in no-property-layers test.
🔇 Additional comments (8)
mesa/visualization/space_drawers.py (2)
85-90: LGTM - Parameter naming improved.The parameter rename from
space_kwargstodraw_space_kwargsmakes the API more explicit and clear.
126-133: LGTM - Consistent parameter naming.The parameter rename from
chart_kwargstodraw_chart_kwargsis consistent with the matplotlib path changes.mesa/visualization/space_renderer.py (5)
7-7: LGTM - Future annotations import.Good practice to enable forward references for type hints.
73-77: Good: Internal state for chainable API.The addition of internal state variables enables the chainable setup/draw pattern, which improves the API ergonomics.
173-186: LGTM - Chainable setup method.The
setup_structure()method follows the builder pattern by returningselffor method chaining.
187-202: LGTM - Chainable setup method for agents.The
setup_agents()method properly stores both the portrayal function and drawing kwargs.
203-217: LGTM - Chainable setup method for property layers.The
setup_propertylayer()method completes the setup API trio.mesa/visualization/solara_viz.py (1)
273-277: Rewrite the review comment: The draw methods are called without setup_* methods, and without ensuring the renderer has configured portrayal functions. This will causecollect_agent_datato crash when trying to callNoneas theagent_portrayalfunction.Either:
- Call
setup_agents(),setup_structure(), andsetup_propertylayer()with appropriate portrayal functions before drawing, or- Provide default portrayal functions (as done in
make_altair_space), or- Document that the renderer must have portrayal pre-configured before being passed to
SpaceRendererComponentVerify the intended API pattern and ensure portrayal is properly initialized.
This comment was marked as off-topic.
This comment was marked as off-topic.
|
I made this kind of in a hurry. I’ll update the tests and add the documentation over the weekend. In the meantime, can you take a look at just the API to see if it’s working fine (it was for me)? |
quaquel
left a comment
There was a problem hiding this comment.
The code looks basically fine to me.
2 points:
- Do we want to keep backward compatibility? I am fine with breaking things, but it's good to discuss this
- All examples still need to be updated. Do you plan to make that part of this PR?
We did just release an API update over on a 3.x version, updating it again in 3.3.x wouldn't be very wise in my opinion.
I intend to, what do you suggest? |
Fair enough, but then we should ensure that we don't break it. So, e.g., def draw_agents(self, *args, **kwargs):
if args or kwargs: # implicit booleanness of empty list/kwarg to be checked if correct
warnings.warn("some message", DeprecationWarning, stack_level=2)
self.agent_portrayal = args[0]
self_draw_kwargs = kwargs
# normal code goes here.
Excellent, fixing it in this pr makes most sense to me. |
EwoutH
left a comment
There was a problem hiding this comment.
Thanks for the effort so far!
Doesn’t need to be this PR (it can), but before we deprecate this officially we should have a section in the migration guide and the deprecation messages should point to that section.
There was a problem hiding this comment.
- You are using a
PendingDerpecationWarning. I am not sure that is the best one to use. See the discussion on stack overflow, I personally favor using aFutureWarning(for all users of a library) these days, or alternatively aDeprecationWarning(for code that uses mesa from within__main__). - There are a few other changes here (e.g., the name change of kwargs in space_drawers, which technically were not needed and might cause trouble for users. Curious to know why you made the change. I am inclined to suggest reverting those changes.
- Have you tested all examples, or are you only relying on the unit tests for this? I just want to ensure that all examples continue to work correctly after this PR is merged.
the discussion also mentions:
and the term
I just wanted to make naming consistent in the backend, this is not user facing, so I don't think we should worry about that. Let me know if you feel otherwise.
I've tested all the examples by running them myself, they will work after this PR is merged if I haven't missed anything. |
|
I will try to write up some guidelines on how we deprecate stuff. Than we don’t have to discuss and reinvent that on every PR. |
|
Ok, fine with me. Let's first agree on deprecation in #2900 and then afterwards merge this. |
|
Could you check if we now follow the policy as described in #2900? |
|
From what I can tell this follows #2900 (step 1). @Sahil-Chhoker and @quaquel is this ready to merge? |
|
just a last check for the deprecations and then yes it's ready to go. |
|
@quaquel your formal review status is still “requested changes”, blocking merging. @Sahil-Chhoker ready to merge, right? |
|
Thanks Jan! @Sahil-Chhoker, we're good? |
|
@EwoutH, CI seems to be failing. |
Summary
SpaceRenderer.PendingDeprecationWarningsto the old API as an indication that it will be deprecated in the future.space_kwargstodraw_space_kwargsandchart_kwargstodraw_chart_kwargsinspace_drawerto keep things consistent with the current APIMotive
Refer to #2874.
Implementation
Separated the draw functions in two parts, setup functions, used to update states and draw functions, used to draw stuff (agents, structure, property layer).
Usage Examples
Additional Notes
@quaquel I couldn't recreate the matplotlib bug, so it would be very helpful if you can provide some kind of example.
Summary by CodeRabbit
Refactor
Tests
Examples
✏️ Tip: You can customize this high-level summary in your review settings.