Skip to content

Commit

Permalink
Initialize experimental adv_tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
rht committed Jun 29, 2023
1 parent 4e36a6a commit 4e75b8f
Showing 1 changed file with 211 additions and 0 deletions.
211 changes: 211 additions & 0 deletions docs/tutorials/adv_tutorial_experimental.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Advanced Tutorial"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For an executable version of this tutorial: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/projectmesa/mesa/main?labpath=docs%2Ftutorials%2Fadv_tutorial_experimental.ipynb) or [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/projectmesa/mesa/blob/main/docs/tutorials/adv_tutorial_experimental.ipynb)\n",
"\n",
"### Adding visualization\n",
"\n",
"So far, we've built a model, run it, and analyzed some output afterwards. However, one of the advantages of agent-based models is that we can often watch them run step by step, potentially spotting unexpected patterns, behaviors or bugs, or developing new intuitions, hypotheses, or insights. Other times, watching a model run can explain it to an unfamiliar audience better than static explanations. Like many ABM frameworks, Mesa allows you to create an interactive visualization of the model. In this section we'll walk through creating a visualization using built-in components, and (for advanced users) how to create a new visualization element.\n",
"\n",
"First, a quick explanation of how Mesa's interactive visualization works. The visualization is done in a browser window, using the [Solara](https://solara.dev/) framework, a pure Python, React-style web framework. Running `solara run app.py` will launch a web server, which runs the model, and displays model detail at each step via the Matplotlib plotting library."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Grid Visualization\n",
"\n",
"To start with, let's have a visualization where we can watch the agents moving around the grid. For this, you will need to put your model code in a separate Python source file. For now, let us use the `MoneyModel` created in the [Introductory Tutorial](https://mesa.readthedocs.io/en/main/tutorials/intro_tutorial.html) saved to `MoneyModel.py` file provided.\n",
"Next, in a new source file (e.g. `MoneyModel_Viz.py`) include the code shown in the following cells to run and avoid Jupyter compatibility issue."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%pip install --quiet mesa\n",
"import mesa\n",
"# If MoneyModel.py is where your code is, do this instead:\n",
"# from MoneyModel import MoneyModel\n",
"\n",
"# To make this tutorial notebook executable in Binder/Colab,\n",
"# we install mesa_models.\n",
"%pip install --quiet git+https://github.com/projectmesa/mesa-examples\n",
"%pip install --quiet solara\n",
"from mesa_models.boltzmann_wealth_model.model import BoltzmannWealthModel"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Mesa's grid visualizer works by looping over every cell in a grid, and generating a portrayal for every agent it finds. A portrayal is a dictionary (which can easily be turned into a JSON object) which tells Matplotlib the color and size of the scatterplot markers (each signifying an agent). The only thing we need to provide is a function which takes an agent, and returns a portrayal dictionary. Here's the simplest one: it'll draw each agent as a blue, filled circle, with a radius size of 50."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"def agent_portrayal(agent):\n",
" return {\n",
" \"color\": \"tab:blue\",\n",
" \"size\": 50,\n",
" }"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to the portrayal method, we instantiate the model parameters, some of which are modifiable by user inputs. In this case, the number of agents, N, is specified as a slider of integers."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model_params = {\n",
" \"N\": {\n",
" \"type\": \"SliderInt\",\n",
" \"value\": 50,\n",
" \"label\": \"Number of agents:\",\n",
" \"min\": 10,\n",
" \"max\": 100,\n",
" \"step\": 1,\n",
" },\n",
" \"width\": 10,\n",
" \"height\": 10,\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we instantiate the visualization object which (by default) displays the grid containing the agents, and timeseries of of values computed by the model's data collector. In this example, we specify the Gini coefficient.\n",
"\n",
"There are 3 buttons:\n",
"- the step button, which advances the model by 1 step\n",
"- the play button, which advances the model indefinitely until it is paused, or until `model.running` is False (you may specify the stopping condition)\n",
"- the pause button, which pauses the model\n",
"\n",
"To reset the model, simply change the model parameter from the user input (e.g. the \"Number of agents\" slider)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"from mesa_models.experimental import JupyterViz\n",
"\n",
"page = JupyterViz(\n",
" BoltzmannWealthModel,\n",
" model_params,\n",
" measures=[\"Gini\"],\n",
" name=\"Money Model\",\n",
" agent_portrayal=agent_portrayal,\n",
")\n",
"# This is required to render the visualization in the Jupyter notebook\n",
"page"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Changing the agents\n",
"\n",
"In the visualization above, all we could see is the agents moving around -- but not how much money they had, or anything else of interest. Let's change it so that agents who are broke (wealth 0) are drawn in red, smaller. (TODO: currently, we can't predict the drawing order of the circles, so a broke agent may be overshadowed by a wealthy agent)\n",
"\n",
"To do this, we go back to our `agent_portrayal` code and add some code to change the portrayal based on the agent properties and launch the server again."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def agent_portrayal(agent):\n",
" size = 10\n",
" color = \"tab:red\"\n",
" if agent.wealth > 0:\n",
" size = 50\n",
" color = \"tab:blue\"\n",
" return {\"size\": size, \"color\": color}"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"page = JupyterViz(\n",
" BoltzmannWealthModel,\n",
" model_params,\n",
" measures=[\"Gini\"],\n",
" name=\"Money Model\",\n",
" agent_portrayal=agent_portrayal,\n",
")\n",
"# This is required to render the visualization in the Jupyter notebook\n",
"page"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Happy Modeling!\n",
"\n",
"This document is a work in progress. If you see any errors, exclusions or have any problems please contact [us](https://github.com/projectmesa/mesa/issues)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

0 comments on commit 4e75b8f

Please sign in to comment.