Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Altair Grid #1902

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open

Introduce Altair Grid #1902

wants to merge 14 commits into from

Conversation

ankitk50
Copy link
Contributor

@ankitk50 ankitk50 commented Dec 8, 2023

Initial implementation of Altair Grid
This is based on one of the implementation by @Corvince in mesa interactive.

Screenshot 2023-12-08 at 06 17 36

@tpike3
Copy link
Member

tpike3 commented Dec 8, 2023

@rlskoeser I know you have been doing some work with altair and Mesa, would you mind taking a look at this?

@tpike3 tpike3 requested a review from Corvince December 8, 2023 12:10
@rlskoeser
Copy link
Contributor

@tpike3 thanks for tagging me, I'm interested to take a look. I probably won't be able to get to it until sometime next week, I hope that's fine. (I'm at the Computational Humanities Research conference and about to give a lightning talk on my simulating risk project!)

Copy link
Contributor

@rlskoeser rlskoeser left a comment

Choose a reason for hiding this comment

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

It's nice to see some altair work going into jupyterviz, I hope my comments are helpful.

import mesa


def get_agent_data_from_coord_iter(data):
Copy link
Contributor

Choose a reason for hiding this comment

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

In my current implementation, I'm using an agent_portrayal method to generate the values needed to draw the space. That may be drawn from the old mesa visualization approach, IDK if there's a good way to pass in something like that to jupyterviz.

I mention because I wonder if it would be cleaner and more explicit than the way you're using json to dump and filter the agent dict.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @rlskoeser; the JSON approach is not very clean. Is there a more explicit way to do this?

Comment on lines 46 to 52
def click_handler(datum):
if datum is None:
return
on_click(model, datum["x"], datum["y"])
update_data()

default_tooltip = [f"{key}:N" for key in data.value[0]]
Copy link
Contributor

Choose a reason for hiding this comment

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

nice that you have tooltip and click handlers - a little hard to assess without documentation, I would want to know how I can customize these

Copy link
Member

Choose a reason for hiding this comment

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

Yes please add docstrings to this explaining how to customize the tooltip

"y:N",
scale=alt.Scale(domain=list(range(model.grid.height - 1, -1, -1))),
),
color=color,
Copy link
Contributor

Choose a reason for hiding this comment

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

In one of my models where I'm using a custom altair space drawer, I'm setting color, size, and shape. Probably reasonable not to support all of those on the first pass, but it would be good to think about a more generalized approach (like the agent portrayal method) that would make it possible to customize this without having to completely re-implement.

Copy link
Member

Choose a reason for hiding this comment

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

I think this should be pretty straightforward to do with the create_grid function

@EwoutH
Copy link
Member

EwoutH commented Dec 17, 2023

@ankitk50 Looks very interesting, could you give the steps on how to run and test this?

@ankitk50
Copy link
Contributor Author

You can run the Boltzmann wealth model with space_drawer = "altair"

Copy link

codecov bot commented Dec 26, 2023

Codecov Report

Attention: 27 lines in your changes are missing coverage. Please review.

Comparison is base (9495a5a) 77.53% compared to head (9dbb494) 78.13%.
Report is 46 commits behind head on main.

Files Patch % Lines
mesa/experimental/altair_grid.py 36.36% 18 Missing and 3 partials ⚠️
mesa/experimental/jupyter_viz.py 62.50% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1902      +/-   ##
==========================================
+ Coverage   77.53%   78.13%   +0.60%     
==========================================
  Files          15       16       +1     
  Lines        1015     1171     +156     
  Branches      221      257      +36     
==========================================
+ Hits          787      915     +128     
- Misses        197      220      +23     
- Partials       31       36       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@EwoutH
Copy link
Member

EwoutH commented Dec 29, 2023

So to run this:

Sorry really haven't played with the visualization yet, but very curious.

(sidenote: We really should put back some basic examples in the main repo #1929)

@ankitk50
Copy link
Contributor Author

So to run this:

Sorry really haven't played with the visualization yet, but very curious.

(sidenote: We really should put back some basic examples in the main repo #1929)

You need to go to the folder boltzmann_wealth_model_experimental and then run solara run app.py

@EwoutH
Copy link
Member

EwoutH commented Dec 29, 2023

Right, so for anyone else wanting to try the visualisation:

  1. Switch to this development branch ankitk50:altair_viz
git remote add ankitk50 https://github.com/ankitk50/mesa.git
git fetch ankitk50
git checkout -b altair_viz ankitk50/altair_viz
  1. Download or clone the mesa-examples repo and move the boltzmann_wealth_model_experimental folder to your
  2. Add space_drawer="altair" to the JupyterViz() instantiation (line 33 of app.py)
  3. Make sure you have solara installed (pip install -U solara)
  4. Open your terminal, make sure your Python environment is activated (default in IDEs like PyCharm), move to the boltzmann_wealth_model_experimental directory and run solara run app.py

@ankitk50 ankitk50 marked this pull request as ready for review January 5, 2024 12:00
@rht
Copy link
Contributor

rht commented Jan 6, 2024

@ankitk50: the Altair version of JupyterViz needs to have a feature parity with the Matplotlib version, and as such, needs the agent_portrayal for generality, as per @rlskoeser's feedbacks (you may read @rlskoeser's Altair space drawer usage). If you want the PR to be merged soon, you need to stay within a precise scope of what it consists of. I see your point in wanting to automatically retrieve all the agent's attributes in your current implementation, but it is out of scope, and we can discuss it in a separate thread.

I'm looking forward to have the Altair version to be the default soon.

Regarding with attribution, @rlskoeser are you OK with being a co-author in @ankitk50's Git commit in this PR, or would you prefer attribution to the code for a derivative work?

@Corvince
Copy link
Contributor

Corvince commented Jan 6, 2024

Maybe I can address some of the points, since this PR is basically copy and pasted from my implementation in mesa-interactive.

The overall idea there is that the visualization just accepts a list of solara widgets*, with no special handling for the space drawer. This also means an agent portrayal is intentionally left out of the implementation. Instead a specialized create_grid function can be used. Everything specific to agent portrayal goes there. Currently it only supports color, but it's simple to extend to other properties (in mesa interactive I just haven't found the time to do so yet). If you need to specialize your visualization beyond what is included on the create_grid function you could just create your own Altair visualization or you use any other library and wrap it in a solara widget.

*It's a bit more complicated actually, since we also want to pass in model data. So you need a function or widget that accepts a model property and returns a widget (or in mesa-interactive wrap it in a static function).

I am not saying this approach is better, it's primarily something I wanted to explore as part of mesa-interactive. Again, unfortunately I hadn't had much time lately to develop it further and have no strong opinion on what is better. Just wanted to give some perspective on why this is implemented the way it is.

Btw @ankitk50 I am fine with you using the code here, but next time it would be a nice gesture to ask first or give credit. No hard feelings though

@ankitk50
Copy link
Contributor Author

ankitk50 commented Jan 6, 2024

Hi @Corvince sorry that I didn't mention use your code. Actually @EwoutH pointed me to use it in one of the discussions, thought you were aware. But nevertheless, should have done it.

@EwoutH EwoutH added feature Release notes label visualisation labels Jan 9, 2024
@rlskoeser
Copy link
Contributor

Regarding with attribution, @rlskoeser are you OK with being a co-author in @ankitk50's Git commit in this PR, or would you prefer attribution to the code for a derivative work?

Sorry for the delay in responding. Co-author commit seems fine here, thanks for asking.

@EwoutH
Copy link
Member

EwoutH commented Jan 16, 2024

What's the state of this PR? Do we want it in 2.2.1?

Since it's all in the experimental space it's okay if this break things, as long as that's somewhat documented.

@ankitk50
Copy link
Contributor Author

I would like to merge it, we can anyways iterate over the ideas and features.

@rht
Copy link
Contributor

rht commented Jan 16, 2024

Since it's all in the experimental space it's okay if this break things, as long as that's somewhat documented.

It's definitely not okay to ignore people's feedback (and I have already spent the time to run the code in this PR) and unilaterally decide it's fine to merge.

@EwoutH
Copy link
Member

EwoutH commented Jan 16, 2024

I meant mainly from a SemVer perspective. What exact feedback still needs to be addressed?

@rht
Copy link
Contributor

rht commented Jan 16, 2024

What exact feedback still needs to be addressed?

#1902 (comment)
#1902 (comment)
#1902 (comment)
#1902 (comment)

I'm not sure how to interpret regarding with ignoring all of those comments as if they don't exist.

In case you wonder about the experimental status of JupyterViz. While it is experimental, it doesn't deviate that much from the previous Tornado viz, and so users may find them more familiar, while mesa-interactive is more speculative. You can't just have 2 viz with conflicting API get merged messily just like that. I'm not sure why as a maintainer, I have to be the one to justify all the reasons why the code I implemented should be fine to be used.

@Corvince
Copy link
Contributor

I agree with @rht that it would be very beneficial if you @ankitk50 could try to address those comments. Most of them are really more suggestions then actionable items, but some statement that you at least have these points on your radar would be nice. Currently, it indeed feels like they are just ignored and that just doesn't feel right. Personally I haven't reviewed this PR yet, because I was also somewhat waiting on what happens as a response to those comments.

@Corvince
Copy link
Contributor

@ankitk50: the Altair version of JupyterViz needs to have a feature parity with the Matplotlib version, and as such, needs the agent_portrayal for generality, as per @rlskoeser's feedbacks

Again, I was waiting on a response to this, but to put forward the discussion, I don't think we need feature parity. The matplotlib version also hasn't feature parity with the tornado stuff, so why make it a requirement suddenly? The scope of this PR is to introduce an altair grid, at for that I think its sufficient.

@rht
Copy link
Contributor

rht commented Jan 16, 2024

The matplotlib version also hasn't feature parity with the tornado stuff, so why make it a requirement suddenly?

The goal is to replace the Matplotlib version of JupyterViz with the Altair version. It shouldn't be that complicated to implement. It's fine if it doesn't have custom portrayal yet, but at the very least, the API needs to stay consistent. Can't have 3 API's (Tornado, Matplotlib JupyterViz, and this PR's Altair grid) that is going to be confusing for the users.
That said, the only missing features from the Matplotlib version are custom marker (e.g. the wolf-sheep PNG portrayals) and the hex grid. Everything else in the mesa-examples has already been covered.

@ankitk50
Copy link
Contributor Author

I would need to maybe align a bit more. Apologies for the confusion but the initial idea was to try Altair grid. The feature only works when you parse it via the agent portrayal. I do not have a complete understanding of the need for the parity. I get the idea that Altair would try to become default , but those changes could be incremental(if not orthogonal) on this PR.

@tpike3
Copy link
Member

tpike3 commented Jan 17, 2024

@ankitk50 I piled on to @rlskoeser comments, if you could address those then we could merge, in general I would emphasize, please add docstrings and comments to make the code more readable.

@EwoutH
Copy link
Member

EwoutH commented Jan 21, 2024

@ankitk50 do you need anything from us to move this forward?

@EwoutH
Copy link
Member

EwoutH commented Jan 22, 2024

I finally have an IDE with Solara support again, so let me know if you need anything fixed, tested or build!

@rlskoeser
Copy link
Contributor

Regarding with attribution, @rlskoeser are you OK with being a co-author in @ankitk50's Git commit in this PR, or would you prefer attribution to the code for a derivative work?

Sorry for the delay in responding. Co-author commit seems fine here, thanks for asking.

I know I said co-author commit previously, but my collaborator thinks that attribution to the code would be better recognition for our project - is that still feasible? Thank you!

@rht
Copy link
Contributor

rht commented Jan 23, 2024

I added an attribution in #1991.

@ankitk50
Copy link
Contributor Author

ankitk50 commented Feb 9, 2024

Can someone merge this @rht @tpike3 @Corvince ?

@@ -144,6 +149,13 @@ def render_in_browser():
ModelController(model, play_interval, current_step, reset_counter)
with solara.Card("Progress", margin=1, elevation=2):
solara.Markdown(md_text=f"####Step - {current_step}")
with solara.Card("Analytics", margin=1, elevation=2):
Copy link
Contributor

Choose a reason for hiding this comment

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

This is unrelated to the PR.

@rht
Copy link
Contributor

rht commented Feb 9, 2024

There is #1991, which is what I requested for the Altair grid to begin with, but wasn't addressed after so much time has passed, so I made my own PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Release notes label visualisation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants