feat: Add tooltip to Altair agent portrayal (#2795)
Summary
This PR adds a tooltip attribute to AgentPortrayalStyle, enabling agent-specific information to be displayed on hover in Altair-based visualizations.
Motive
This feature resolves issue #2795, which requested an easy way to display agent information (like health, status, etc.) directly in the visualization. It is highly useful for debugging and for closely following the state of specific agents during a simulation.
Implementation
The implementation consists of two main changes:
-
AgentPortrayalStyleinportrayal_components.pywas extended to include atooltip: dict | None = Noneattribute. - The
collect_agent_dataanddraw_agentsmethods inaltair_backend.pywere updated to process this newtooltipdata. The backend now correctly creates a Pandas DataFrame with the tooltip columns and adds them to the Altair chart'stooltipencoding channel.
Usage Examples
Users can now pass a dictionary to the tooltip attribute within their agent_portrayal function.
def agent_portrayal(agent):
return AgentPortrayalStyle(
color=agent.wealth,
tooltip={"Agent ID": agent.unique_id, "Wealth": agent.wealth},
)
This provides a much richer user experience for inspecting agents.
Before:
Hovering over an agent only displayed basic coordinate information.
After:
Hovering over an agent now displays the custom information defined in the tooltip dictionary.
Additional Notes
As discussed in the original issue, this implementation is specific to the Altair backend. A similar feature for the Matplotlib backend is not feasible in an elegant way at this time.
<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit
- New Features
- Agent tooltips now show ID and Wealth in the wealth model example; Altair backend displays per-agent hover data.
- Refactor
- Visualization data pipeline rewritten to use record-based agent data for more consistent color/shape encodings and legends.
- Bug Fixes
- Matplotlib backend now rejects tooltips (Altair-only) to prevent unsupported usage.
- Documentation
- Expanded docs describing visualization behavior and tooltip support.
- Tests
- Added tests covering tooltip support in the Altair backend.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Performance benchmarks:
| Model | Size | Init time [95% CI] | Run time [95% CI] |
|---|---|---|---|
| BoltzmannWealth | small | 🔵 +0.6% [-0.0%, +1.2%] | 🔵 +0.0% [-0.2%, +0.2%] |
| BoltzmannWealth | large | 🔵 -2.3% [-2.9%, -1.6%] | 🔵 -1.2% [-1.5%, -0.9%] |
| Schelling | small | 🔵 -0.6% [-0.9%, -0.2%] | 🔵 +0.9% [+0.6%, +1.2%] |
| Schelling | large | 🔵 -0.9% [-1.2%, -0.5%] | 🔵 +0.9% [+0.2%, +1.6%] |
| WolfSheep | small | 🔵 -0.4% [-0.7%, -0.0%] | 🔵 -0.5% [-1.1%, +0.3%] |
| WolfSheep | large | 🔵 -0.9% [-1.1%, -0.7%] | 🔵 -2.0% [-2.3%, -1.6%] |
| BoidFlockers | small | 🔵 -2.8% [-3.4%, -2.3%] | 🔵 -1.9% [-2.2%, -1.6%] |
| BoidFlockers | large | 🔵 -2.1% [-2.8%, -1.3%] | 🔵 -0.7% [-1.5%, +0.2%] |
Hi this is my first time contributing to Mesa , is this acceptable? , what changes do I need to make to my commit to get the PR merged?
@coderabbitai review
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
Walkthrough
Adds per-agent tooltip support to portrayals and Altair rendering, refactors Altair data prep to records with tooltip propagation and shape-domain extraction, updates example app to emit tooltips and change color encoding, adds Matplotlib validation forbidding tooltips, and updates tests to include tooltip data.
Changes
| Cohort / File(s) | Summary of changes |
|---|---|
Example app updatesmesa/examples/basic/boltzmann_wealth_model/app.py |
Add per-agent tooltip (Agent ID, Wealth) to portrayals; adjust color encoding usage in post-processing; simplify SpaceRenderer.draw_agents invocation by removing explicit cmap/vmin/vmax args. |
Altair backend draw_agents refactormesa/visualization/backends/altair_backend.py |
Build agent data as records (list of dicts) including optional tooltip; coerce numeric columns post-DataFrame creation; derive tooltip key dynamically; use original_color:Q when numeric, otherwise use fill color; extract unique shape domain; update docstrings. |
Portrayal components extensionmesa/visualization/components/portrayal_components.py |
Add public attribute `tooltip: dict |
Matplotlib backend validationmesa/visualization/backends/matplotlib_backend.py |
Remove CORRECTION_FACTOR_MARKER_ZOOM constant; add validation to reject tooltip in AgentPortrayalStyle for Matplotlib (raises ValueError). |
Tests alignmenttests/test_backends.py |
Include tooltip field in Altair draw_agents test inputs to match new data structure handling. |
Sequence Diagram(s)
sequenceDiagram
autonumber
participant App as Example App
participant SR as SpaceRenderer
participant AB as AltairBackend
participant Altair as Altair Chart
App->>SR: call draw_agents(..., portrayals with tooltip)
SR->>AB: pass agent portrayals (records-oriented)
AB->>AB: build records per agent (x,y,color,shape,tooltip,...)
AB->>Altair: create encodings (color (original_color:Q or fill), shape domain, tooltip key)
Altair-->>App: interactive chart (legend, shapes, tooltips)
note right of AB: Tooltip key chosen from first valid record
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
- projectmesa/mesa#2786 — Introduced
AgentPortrayalStyle/PropertyLayerStyle; directly related as this PR extendsAgentPortrayalStylewithtooltipand adapts backends. - projectmesa/mesa#XXXX — (if applicable) prior Altair rendering changes that touch color/encoding decisions — consider reviewing alongside this change.
Suggested labels
enhancement, visualisation
Suggested reviewers
- quaquel
- tpike3
Poem
A twitch of whiskers, tooltips bright,
I hop through charts by day and night.
Shapes align and legends sing,
Data carrots on a string.
Click and see each agent’s tale—
A rabbit’s triumph, small and hale. 🥕
Pre-merge checks and finishing touches
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Description Check | ⚠️ Warning | The description does not follow the repository’s official PR template prompt and lacks the required boilerplate that directs the author to select a bug fix or feature template via the Preview tab, so it fails to conform to the prescribed structure. | Please update the PR description to use the repository’s feature/enhancement template by selecting it from the Preview tab, ensuring the standard template introduction and all required sections are included. |
✅ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title Check | ✅ Passed | The title clearly summarizes the primary change by indicating the addition of tooltip support for agent portrayals in the Altair backend and follows conventional “feat:” prefix usage in a concise, single sentence. |
| Docstring Coverage | ✅ Passed | Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%. |
✨ Finishing touches
- [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
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 @coderabbitai help to get the list of available commands and usage tips.
Hi this is my first time contributing to Mesa , is this acceptable? , what changes do I need to make to my commit to get the PR merged?
Thanks a lot for this PR. It's great to see this, and this is most definitely an acceptable PR. I particularly appreciate the fact that you also included a small update to the tests.
Some minor comments.
- You changed the wording in some of the docs from colorbar to colormap. I guess the latter is more correct, but technically, this is a separate issue from the tooltip, which is at the core of this PR. Ideally, we like PRs to be atomic, meaning they address a single issue.
- Coderrabbit also has a suggestion on empty dicts that is worth looking at. You are best positioned to judge if the AI suggestion is actually correct or not.
- It would be good to make very clear in the documentation of
AgentPortrayalStylethat the tooltip only works with the Altair backend. I probably would even raise aValueErroriftooltipis provided with the matplotlib backend because errors should not be passed over silently.
@quaquel thanks a lot for your valuable feedback , I will attempt to make the above changes asap and update the PR so that it can be merged soon, pleasure contributing to Mesa.
Hi @quaquel , thank you again for the excellent feedback. I've updated the PR to address all your points and the suggestions from coderabbitai: The typo in the PropertyLayerStyle docstring is now corrected. I've implemented the coderabbitai suggestion for a more consistent truthiness check in the Altair backend. The AgentPortrayalStyle docstring for the tooltip attribute now clearly states that it is only for the Altair backend. The Matplotlib backend will now raise a ValueError if a user attempts to use the tooltip attribute, preventing silent failures. All the CI checks should now be passing. Please let me know if there's anything else needed in order to merge this PR.
Hi maintainers @quaquel @tpike3 , just wondering, what's the status on the PR, is it mergeable or do I need to make any further changes?
Thanks for the clarification. This is a part of the code base I am not presently intimately familiar with. I have asked someone who is to also take a look to ensure everything is in order.
@coderabbitai review
✅ Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
@DipayanDasgupta, are you still working on this PR? Some of the review comments haven’t been addressed yet.
Ya , I was preoccupied with some other commitments for the past few days, can you give a final list of changes to be addressed, as far as I recall I had implemented most of the changes you had requested. That being said I'll look into it ASAP and revert back to you
Please just go through the previous review comments, I also didn't get the chance to test run the code to make sure no new bugs are introduced, so I'll be doing that.
@Sahil-Chhoker I have addressed all the issues you highlighted in the code from my side as far as I am aware, please look into the code one last time and merge it , if you find anything else for me to fix/ work upon or you feel is unresolved I am more than happy to do the needful.
I had made the changes 2 weeks back but didn't tag you in a comment , assuming it would be looked into , perhaps that's why it went unnoticed. But regardless I hope you can look into it when you are free.
Thanks @DipayanDasgupta for the changes! This is a crucial PR that changes the backend’s behavior, so I’d like to give it a thorough review when I get some time. Right now my hands are tied with uni. I should have time around Christmas; until then this PR will have to wait. Sorry!
@Sahil-Chhoker works. Please update me when you will be pushing it.