GithubHelp home page GithubHelp logo

Comments (20)

rht avatar rht commented on June 23, 2024 1

I looked at the Solara frontend in Mesa (long overdue) and am wondering whether a dedicated frontend for Mesa-Geo is needed at all, since we can simple feed a matplotlib figure (i.e., solara.FigureMatplotlib) into JupyterViz.

That's a good idea. If the redraws performance is reasonable (with PNG output, projectmesa/mesa#1819), this should do. Then the ipyleaflet implementation would be for performance optimization.

On a side note, if Mesa agents could be retrieved as dataframe in a similar way, then probably agent_portrayal is not need in Mesa either. Currently there is get_agent_vars_dataframe but it would need agent reporters, which is for something else.

agent_portrayal is needed so that user doesn't have to write their own space_drawer, for most use cases, in that they just have to declaratively specify the params.
But it is possible to instead define a space_drawer function preparer that can be imported, that takes in agent_portrayal, and returns a space_drawer(model). This seems to be more general.

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

Hi @Corvince, will you be interested in taking a look at this? @tpike3 and I are probably going to talk about Mesa & Mesa-Geo in an upcoming conference in early Nov. We're thinking to create a tutorial using one of our example models.

Sorry about this short notice. But having a Solora frontend for Mesa-Geo would be super useful : )

from mesa-geo.

Corvince avatar Corvince commented on June 23, 2024

Sorry, I thought I had already answered here. Yes, I would be interested to implement a solara-based frontend. In fact I am working in this right now

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

Great! Looking forward to your implementation. This will be very helpful.

from mesa-geo.

Corvince avatar Corvince commented on June 23, 2024

An update on things I tried so far:

I wanted to leverage Ipyleaflet to have a leaflet map that is similar to what is included currently with the old frontend. After some troubles converting the agents to a compatible GeoJSON format (solara had some issues), I realized this is not needed and we can just pass in a GeoDataFrame.

We can get that easily with

gdf = model.space.get_agents_as_GeoDataFrame().to_crs("epsg:4326")

With this we can create a ipyleaflet map with something like this

import ipyleaflet

center_default = (53.2305799, 6.5323552)
zoom_default = 5

ipyleaflet.Map(
    center=center_default,
    zoom=zoom_default,
    layers=[
        ipyleaflet.TileLayer(),
        ipyleaflet.GeoData(
            geo_dataframe=gdf,
            style={
                "color": "blue",
                "fillColor": "#3366cc",
                "opacity": 0.05,
                "weight": 1.9,
                "dashArray": "2",
                "fillOpacity": 0.6,
            },
        ),
    ],
)

The problematic thing is coloring the agents based on some property. In leaflet we could define the color in terms of its feature with a function that maps a feature to a color. But this doesn't seem to be possible with IPyleaflet. We could probably create different layers for each color, but I haven't tried.

The other possibility would be to leverage Altair. Here we can define the colors decleratively like so:

import altair as alt

alt.Chart(data=gdf).mark_geoshape().encode(color="atype:O")

However, including a basemap is not super well supported, but might be possible, see vega/vega-lite#5758

And the output needs some finetuning.

But I won't be able to investigate this further until beginning of November. So whats the current timeline for the tutorial @wang-boyu ?

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

I'm so glad that you're looking into this! Thank you! Was worried about it in the past few days.

There is a dev meeting tomorrow and I'll discuss with @tpike3 about the tutorial. After that I'll post an update here.

from mesa-geo.

tpike3 avatar tpike3 commented on June 23, 2024

The tutorial is at the beginning of November (Nov2nd or 3rd) @Corvince would you have a branch you can push so I can just build off what you have already done?

from mesa-geo.

Corvince avatar Corvince commented on June 23, 2024

Unfortunately not, but it boils down to the code snippets I posted. I can try to assist if you have questions, but I don't have access to my laptop until Nov.

But both approaches should be possible to wrap in a function like the current grid or space views that accept model and agent_portrayal as their arguments. From there you can generate the geodataframe and return either the solara leaflet or Altair figure

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

Since we're not really ready for the tutorial, we're going to skip the CSSSA session this year (@tpike3 will still be there to give a Mesa tutorial and may possibly mention Mesa-Geo briefly, but not a full tutorial for Mesa-Geo).

The next window is the online tutorial series from CSSSA (link to the Mesa online tutorial by @tpike3: youtu.be/8P5P7NpCx5o) which is currently scheduled at Feb 2024 for Mesa-Geo. Would be great if we can have the feature and the tutorial ready by then : )

from mesa-geo.

Corvince avatar Corvince commented on June 23, 2024

That sounds doable!

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

I looked at the Solara frontend in Mesa (long overdue) and am wondering whether a dedicated frontend for Mesa-Geo is needed at all, since we can simple feed a matplotlib figure (i.e., solara.FigureMatplotlib) into JupyterViz.

For example users could define such a function in this way:

def space_drawer(model):
    agents_gdf = model.space.get_agents_as_GeoDataFrame()
    fig, ax = plt.subplots()

    # users do some plotting here with geopandas, for example:
    agents_gdf.plot(column="some_col", ax=ax)

    # similarly for raster layers
    for layer in model.space.layers:
        if isinstance(layer, RasterLayer):
            ... # plot it using rasterio or matplotlib or any other library that is based on matplotlib

    return solara.FigureMatplotlib(fig)

The benefits are that, for the users, they don't need to learn how to make plots in Mesa (e.g., is it "color" or "Color" in agent_portrayal). They only need to know how to use the visualization tools they choose. For us developers, we don't need to maintain agent_portrayal and how to integrate it with backend plotting libraries.

The catch here is that JupyterViz expects space_drawer to be space_drawer(model, agent_portrayal), not space_drawer(model).

On a side note, if Mesa agents could be retrieved as dataframe in a similar way, then probably agent_portrayal is not need in Mesa either. Currently there is get_agent_vars_dataframe but it would need agent reporters, which is for something else.

Any thoughts on this?

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

Made a simple demo for this with the GeoSchellingPoints model: https://github.com/wang-boyu/mesa-examples/blob/gis%2Fsolara-frontend/gis/geo_schelling_points/app.ipynb

from mesa-geo.

rht avatar rht commented on June 23, 2024

What functionalities are missing in that demo in comparison to the mesa-viz-tornado version?

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

What functionalities are missing in that demo in comparison to the mesa-viz-tornado version?

Good question! One thing that I didn't do in the demo is to have some popup properties, so that users can click an agent on the map and see some descriptions. Not sure how this will work with Solara.

It is mainly a different way of doing things with these two approaches. Previously in agent_portrayal we will do something like this:

# `agent` is an object of type `GeoAgent`
if agent.red_cnt > agent.blue_cnt:
    portrayal["color"] = "Red"
elif agent.red_cnt < agent.blue_cnt:
    portrayal["color"] = "Blue"
else:
    portrayal["color"] = "Grey"

whereas now we need to do

# `region_agents` is a GeoDataFrame
region_agents["is_red"] = region_agents["red_cnt"] > region_agents["blue_cnt"]

# Then figure out the color palette you want with geopandas plot, or simply use the default (do nothing)
color_map = mpl.colors.ListedColormap(plt.cm.Set2.colors[:2])
region_agents.plot(column="is_red", cmap=color_map, alpha=0.5, ax=space_ax)

Operating at the GeoDataFrame level may appear simple in this demo. But back in agent_portrayal we could do really complicated if-else conditions. For example if the color depends on neighbors statuses. But the GeoDataFrame approach may not work in this case, because the data is already extracted as dataframe, and we wouldn't be able to know which rows (agents) are the neighbors of other rows (agents).

In this case we may need to go back to the geoagent code, and think about how to write what we want as an attribute, so that it could be exported as a column of the GeoDataFrame. In fact this sounds a good practice even for the agent_portrayal approach, to avoid complex if-else conditions in the portrayal function.

from mesa-geo.

rht avatar rht commented on June 23, 2024

In this case we may need to go back to the geoagent code, and think about how to write what we want as an attribute, so that it could be exported as a column of the GeoDataFrame. In fact this sounds a good practice even for the agent_portrayal approach, to avoid complex if-else conditions in the portrayal function.

That makes sense, in that the agent_portrayal should be about declaring the output detail. The DF output would constraint the user to do this.

I think it is sufficient to merge the Solara demo, with a documentation that says the rendering is not clickable, and that the clickable version is still in the work, pointing to this issue.

We should discuss about removing the agent_portrayal argument from the custom space drawer in the next dev meeting. I am on board with it. It reduces unnecessary hardcoded structure that the user has to learn. It's like having a web browser with as few chrome components as possible, and more customizable HTML elements instead.

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

We should discuss about removing the agent_portrayal argument from the custom space drawer in the next dev meeting. I am on board with it. It reduces unnecessary hardcoded structure that the user has to learn.

How about making it optional... Now I think about it, removing it would need users to know how to use pandas to manipulate and plot dataframes, whereas agent_portrayal requires basic python knowledge. For developers, removing it definitely lightens the burden. But yeah let's talk more in the dev meeting.

from mesa-geo.

maltevogl avatar maltevogl commented on June 23, 2024

I would be interested in this feature a lot. Is there any news on the progress?

from mesa-geo.

EwoutH avatar EwoutH commented on June 23, 2024

I think we're stabilizing JupyterViz in main Mesa first (see projectmesa/mesa#2090), then build the mesa-geo on it. Except if @wang-boyu has an other vision on it.

from mesa-geo.

wang-boyu avatar wang-boyu commented on June 23, 2024

@tpike3 has been working on it with a recent PR #199 as well as an example projectmesa/mesa-examples#117. But they are not merged yet.

from mesa-geo.

maltevogl avatar maltevogl commented on June 23, 2024

Thanks for the feedback, I ll have a look at the examples above.

from mesa-geo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.