Mesa 3.0.0b1__py3-none-any.whl → 3.0.0rc0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of Mesa might be problematic. Click here for more details.
- mesa/__init__.py +1 -3
- mesa/agent.py +23 -8
- mesa/batchrunner.py +26 -1
- {examples → mesa/examples}/README.md +11 -11
- mesa/examples/__init__.py +21 -0
- {examples → mesa/examples}/advanced/epstein_civil_violence/Readme.md +3 -2
- examples/advanced/epstein_civil_violence/epstein_civil_violence/agent.py → mesa/examples/advanced/epstein_civil_violence/agents.py +44 -38
- mesa/examples/advanced/epstein_civil_violence/app.py +73 -0
- mesa/examples/advanced/epstein_civil_violence/model.py +114 -0
- examples/advanced/pd_grid/readme.md → mesa/examples/advanced/pd_grid/Readme.md +4 -3
- mesa/examples/advanced/pd_grid/app.py +54 -0
- {examples/advanced/pd_grid → mesa/examples/advanced}/pd_grid/model.py +1 -2
- {examples → mesa/examples}/advanced/sugarscape_g1mt/Readme.md +6 -29
- examples/advanced/sugarscape_g1mt/sugarscape_g1mt/trader_agents.py → mesa/examples/advanced/sugarscape_g1mt/agents.py +26 -3
- {examples → mesa/examples}/advanced/sugarscape_g1mt/app.py +19 -18
- {examples/advanced/sugarscape_g1mt → mesa/examples/advanced}/sugarscape_g1mt/model.py +6 -6
- {examples → mesa/examples}/advanced/sugarscape_g1mt/tests.py +3 -6
- mesa/examples/advanced/wolf_sheep/app.py +84 -0
- {examples/advanced/wolf_sheep → mesa/examples/advanced}/wolf_sheep/model.py +9 -8
- mesa/examples/basic/boid_flockers/Readme.md +22 -0
- {examples → mesa/examples}/basic/boid_flockers/app.py +3 -4
- {examples → mesa/examples}/basic/boid_flockers/model.py +1 -2
- {examples → mesa/examples}/basic/boltzmann_wealth_model/Readme.md +1 -5
- mesa/examples/basic/boltzmann_wealth_model/__init__.py +0 -0
- {examples → mesa/examples}/basic/boltzmann_wealth_model/app.py +15 -12
- {examples → mesa/examples}/basic/boltzmann_wealth_model/model.py +3 -4
- {examples → mesa/examples}/basic/conways_game_of_life/Readme.md +11 -7
- mesa/examples/basic/conways_game_of_life/__init__.py +0 -0
- {examples → mesa/examples}/basic/conways_game_of_life/agents.py +8 -8
- mesa/examples/basic/conways_game_of_life/app.py +51 -0
- {examples → mesa/examples}/basic/conways_game_of_life/model.py +3 -4
- {examples → mesa/examples}/basic/conways_game_of_life/st_app.py +2 -1
- examples/basic/schelling/README.md → mesa/examples/basic/schelling/Readme.md +2 -9
- mesa/examples/basic/schelling/__init__.py +0 -0
- {examples → mesa/examples}/basic/schelling/app.py +6 -7
- {examples → mesa/examples}/basic/schelling/model.py +1 -2
- mesa/examples/basic/virus_on_network/__init__.py +0 -0
- mesa/examples/basic/virus_on_network/app.py +114 -0
- {examples → mesa/examples}/basic/virus_on_network/model.py +4 -7
- mesa/experimental/cell_space/discrete_space.py +6 -0
- mesa/experimental/devs/eventlist.py +6 -0
- mesa/model.py +13 -0
- mesa/space.py +70 -35
- mesa/visualization/__init__.py +16 -5
- mesa/visualization/components/__init__.py +83 -0
- mesa/visualization/components/altair_components.py +188 -0
- mesa/visualization/components/matplotlib_components.py +176 -0
- mesa/visualization/mpl_space_drawing.py +558 -0
- mesa/visualization/solara_viz.py +30 -20
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/METADATA +1 -3
- mesa-3.0.0rc0.dist-info/RECORD +95 -0
- examples/advanced/epstein_civil_violence/epstein_civil_violence/model.py +0 -146
- examples/advanced/epstein_civil_violence/epstein_civil_violence/portrayal.py +0 -33
- examples/advanced/epstein_civil_violence/epstein_civil_violence/server.py +0 -81
- examples/advanced/epstein_civil_violence/requirements.txt +0 -3
- examples/advanced/epstein_civil_violence/run.py +0 -3
- examples/advanced/pd_grid/pd_grid/portrayal.py +0 -19
- examples/advanced/pd_grid/pd_grid/server.py +0 -21
- examples/advanced/pd_grid/requirements.txt +0 -3
- examples/advanced/pd_grid/run.py +0 -3
- examples/advanced/sugarscape_g1mt/requirements.txt +0 -6
- examples/advanced/sugarscape_g1mt/run.py +0 -105
- examples/advanced/sugarscape_g1mt/sugarscape_g1mt/resource_agents.py +0 -26
- examples/advanced/sugarscape_g1mt/sugarscape_g1mt/server.py +0 -61
- examples/advanced/wolf_sheep/requirements.txt +0 -1
- examples/advanced/wolf_sheep/run.py +0 -3
- examples/advanced/wolf_sheep/wolf_sheep/resources/sheep.png +0 -0
- examples/advanced/wolf_sheep/wolf_sheep/resources/wolf.png +0 -0
- examples/advanced/wolf_sheep/wolf_sheep/server.py +0 -78
- examples/basic/__init__.py +0 -13
- examples/basic/boid_flockers/Readme.md +0 -43
- examples/basic/conways_game_of_life/portrayal.py +0 -18
- examples/basic/conways_game_of_life/requirements.txt +0 -1
- examples/basic/conways_game_of_life/server.py +0 -11
- examples/basic/virus_on_network/app.py +0 -133
- mesa/cookiecutter-mesa/cookiecutter.json +0 -8
- mesa/cookiecutter-mesa/hooks/post_gen_project.py +0 -13
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md +0 -4
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate +0 -27
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate +0 -11
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +0 -1
- mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate +0 -60
- mesa/examples.py +0 -3
- mesa/main.py +0 -65
- mesa/visualization/components/altair.py +0 -88
- mesa/visualization/components/matplotlib.py +0 -342
- mesa-3.0.0b1.dist-info/RECORD +0 -114
- {examples → mesa/examples/advanced}/__init__.py +0 -0
- {examples → mesa/examples}/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +0 -0
- {examples/advanced → mesa/examples/advanced/epstein_civil_violence}/__init__.py +0 -0
- {examples/advanced/epstein_civil_violence/epstein_civil_violence → mesa/examples/advanced/pd_grid}/__init__.py +0 -0
- /examples/advanced/pd_grid/pd_grid/agent.py → /mesa/examples/advanced/pd_grid/agents.py +0 -0
- {examples → mesa/examples}/advanced/pd_grid/analysis.ipynb +0 -0
- {examples/advanced/pd_grid/pd_grid → mesa/examples/advanced/sugarscape_g1mt}/__init__.py +0 -0
- {examples/advanced/sugarscape_g1mt → mesa/examples/advanced}/sugarscape_g1mt/sugar-map.txt +0 -0
- {examples → mesa/examples}/advanced/wolf_sheep/Readme.md +0 -0
- {examples/advanced/sugarscape_g1mt/sugarscape_g1mt → mesa/examples/advanced/wolf_sheep}/__init__.py +0 -0
- {examples/advanced/wolf_sheep → mesa/examples/advanced}/wolf_sheep/agents.py +0 -0
- {examples/advanced/wolf_sheep → mesa/examples/basic}/__init__.py +0 -0
- {examples/advanced/wolf_sheep/wolf_sheep → mesa/examples/basic/boid_flockers}/__init__.py +0 -0
- {examples → mesa/examples}/basic/boid_flockers/agents.py +0 -0
- {examples → mesa/examples}/basic/boltzmann_wealth_model/agents.py +0 -0
- {examples → mesa/examples}/basic/boltzmann_wealth_model/st_app.py +0 -0
- {examples → mesa/examples}/basic/schelling/agents.py +0 -0
- {examples → mesa/examples}/basic/schelling/analysis.ipynb +0 -0
- /examples/basic/virus_on_network/README.md → /mesa/examples/basic/virus_on_network/Readme.md +0 -0
- {examples → mesa/examples}/basic/virus_on_network/agents.py +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/WHEEL +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/entry_points.txt +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/licenses/LICENSE +0 -0
- {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import mesa
|
|
2
|
-
from wolf_sheep.agents import GrassPatch, Sheep, Wolf
|
|
3
|
-
from wolf_sheep.model import WolfSheep
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def wolf_sheep_portrayal(agent):
|
|
7
|
-
if agent is None:
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
portrayal = {}
|
|
11
|
-
|
|
12
|
-
if type(agent) is Sheep:
|
|
13
|
-
portrayal["Shape"] = "wolf_sheep/resources/sheep.png"
|
|
14
|
-
# https://icons8.com/web-app/433/sheep
|
|
15
|
-
portrayal["scale"] = 0.9
|
|
16
|
-
portrayal["Layer"] = 1
|
|
17
|
-
|
|
18
|
-
elif type(agent) is Wolf:
|
|
19
|
-
portrayal["Shape"] = "wolf_sheep/resources/wolf.png"
|
|
20
|
-
# https://icons8.com/web-app/36821/German-Shepherd
|
|
21
|
-
portrayal["scale"] = 0.9
|
|
22
|
-
portrayal["Layer"] = 2
|
|
23
|
-
portrayal["text"] = round(agent.energy, 1)
|
|
24
|
-
portrayal["text_color"] = "White"
|
|
25
|
-
|
|
26
|
-
elif type(agent) is GrassPatch:
|
|
27
|
-
if agent.fully_grown:
|
|
28
|
-
portrayal["Color"] = ["#00FF00", "#00CC00", "#009900"]
|
|
29
|
-
else:
|
|
30
|
-
portrayal["Color"] = ["#84e184", "#adebad", "#d6f5d6"]
|
|
31
|
-
portrayal["Shape"] = "rect"
|
|
32
|
-
portrayal["Filled"] = "true"
|
|
33
|
-
portrayal["Layer"] = 0
|
|
34
|
-
portrayal["w"] = 1
|
|
35
|
-
portrayal["h"] = 1
|
|
36
|
-
|
|
37
|
-
return portrayal
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
canvas_element = mesa.visualization.CanvasGrid(wolf_sheep_portrayal, 20, 20, 500, 500)
|
|
41
|
-
chart_element = mesa.visualization.ChartModule(
|
|
42
|
-
[
|
|
43
|
-
{"Label": "Wolves", "Color": "#AA0000"},
|
|
44
|
-
{"Label": "Sheep", "Color": "#666666"},
|
|
45
|
-
{"Label": "Grass", "Color": "#00AA00"},
|
|
46
|
-
]
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
model_params = {
|
|
50
|
-
# The following line is an example to showcase StaticText.
|
|
51
|
-
"title": mesa.visualization.StaticText("Parameters:"),
|
|
52
|
-
"grass": mesa.visualization.Checkbox("Grass Enabled", True),
|
|
53
|
-
"grass_regrowth_time": mesa.visualization.Slider("Grass Regrowth Time", 20, 1, 50),
|
|
54
|
-
"initial_sheep": mesa.visualization.Slider(
|
|
55
|
-
"Initial Sheep Population", 100, 10, 300
|
|
56
|
-
),
|
|
57
|
-
"sheep_reproduce": mesa.visualization.Slider(
|
|
58
|
-
"Sheep Reproduction Rate", 0.04, 0.01, 1.0, 0.01
|
|
59
|
-
),
|
|
60
|
-
"initial_wolves": mesa.visualization.Slider("Initial Wolf Population", 50, 10, 300),
|
|
61
|
-
"wolf_reproduce": mesa.visualization.Slider(
|
|
62
|
-
"Wolf Reproduction Rate",
|
|
63
|
-
0.05,
|
|
64
|
-
0.01,
|
|
65
|
-
1.0,
|
|
66
|
-
0.01,
|
|
67
|
-
description="The rate at which wolf agents reproduce.",
|
|
68
|
-
),
|
|
69
|
-
"wolf_gain_from_food": mesa.visualization.Slider(
|
|
70
|
-
"Wolf Gain From Food Rate", 20, 1, 50
|
|
71
|
-
),
|
|
72
|
-
"sheep_gain_from_food": mesa.visualization.Slider("Sheep Gain From Food", 4, 1, 10),
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
server = mesa.visualization.ModularServer(
|
|
76
|
-
WolfSheep, [canvas_element, chart_element], "Wolf Sheep Predation", model_params
|
|
77
|
-
)
|
|
78
|
-
server.port = 8521
|
examples/basic/__init__.py
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from .boid_flockers.model import BoidFlockers
|
|
2
|
-
from .boltzmann_wealth_model.model import BoltzmannWealthModel
|
|
3
|
-
from .conways_game_of_life.model import ConwaysGameOfLife
|
|
4
|
-
from .schelling.model import Schelling
|
|
5
|
-
from .virus_on_network.model import VirusOnNetwork
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"BoidFlockers",
|
|
9
|
-
"BoltzmannWealthModel",
|
|
10
|
-
"ConwaysGameOfLife",
|
|
11
|
-
"Schelling",
|
|
12
|
-
"VirusOnNetwork",
|
|
13
|
-
]
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Boids Flockers
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
|
|
5
|
-
An implementation of Craig Reynolds's Boids flocker model. Agents (simulated birds) try to fly towards the average position of their neighbors and in the same direction as them, while maintaining a minimum distance. This produces flocking behavior.
|
|
6
|
-
|
|
7
|
-
This model tests Mesa's continuous space feature, and uses numpy arrays to represent vectors. It also demonstrates how to create custom visualization components.
|
|
8
|
-
|
|
9
|
-
## Installation
|
|
10
|
-
|
|
11
|
-
To install the dependencies use pip and the requirements.txt in this directory. e.g.
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
$ pip install -r requirements.txt
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## How to Run
|
|
18
|
-
|
|
19
|
-
* To launch the visualization interactively, run ``mesa runserver`` in this directory. e.g.
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
$ mesa runserver
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
or
|
|
26
|
-
|
|
27
|
-
Directly run the file ``run.py`` in the terminal. e.g.
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
$ python run.py
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
* Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run.
|
|
34
|
-
|
|
35
|
-
## Files
|
|
36
|
-
|
|
37
|
-
* [model.py](model.py): Core model file; contains the Boid Model and Boid Agent class.
|
|
38
|
-
* [app.py](app.py): Visualization code.
|
|
39
|
-
|
|
40
|
-
## Further Reading
|
|
41
|
-
|
|
42
|
-
The following link can be visited for more information on the boid flockers model:
|
|
43
|
-
https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/modeling-natural-systems/boids.html
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
def portrayCell(cell):
|
|
2
|
-
"""This function is registered with the visualization server to be called
|
|
3
|
-
each tick to indicate how to draw the cell in its current state.
|
|
4
|
-
:param cell: the cell in the simulation
|
|
5
|
-
:return: the portrayal dictionary.
|
|
6
|
-
"""
|
|
7
|
-
if cell is None:
|
|
8
|
-
raise AssertionError
|
|
9
|
-
return {
|
|
10
|
-
"Shape": "rect",
|
|
11
|
-
"w": 1,
|
|
12
|
-
"h": 1,
|
|
13
|
-
"Filled": "true",
|
|
14
|
-
"Layer": 0,
|
|
15
|
-
"x": cell.x,
|
|
16
|
-
"y": cell.y,
|
|
17
|
-
"Color": "black" if cell.isAlive else "white",
|
|
18
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
mesa~=2.0
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import mesa
|
|
2
|
-
|
|
3
|
-
from .model import ConwaysGameOfLife
|
|
4
|
-
from .portrayal import portrayCell
|
|
5
|
-
|
|
6
|
-
# Make a world that is 50x50, on a 250x250 display.
|
|
7
|
-
canvas_element = mesa.visualization.CanvasGrid(portrayCell, 50, 50, 250, 250)
|
|
8
|
-
|
|
9
|
-
server = mesa.visualization.ModularServer(
|
|
10
|
-
ConwaysGameOfLife, [canvas_element], "Game of Life", {"height": 50, "width": 50}
|
|
11
|
-
)
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import math
|
|
2
|
-
|
|
3
|
-
import solara
|
|
4
|
-
from matplotlib.figure import Figure
|
|
5
|
-
from matplotlib.ticker import MaxNLocator
|
|
6
|
-
|
|
7
|
-
from mesa.visualization import Slider, SolaraViz, make_space_matplotlib
|
|
8
|
-
|
|
9
|
-
from .model import State, VirusOnNetwork, number_infected
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def agent_portrayal(graph):
|
|
13
|
-
def get_agent(node):
|
|
14
|
-
return graph.nodes[node]["agent"][0]
|
|
15
|
-
|
|
16
|
-
edge_width = []
|
|
17
|
-
edge_color = []
|
|
18
|
-
for u, v in graph.edges():
|
|
19
|
-
agent1 = get_agent(u)
|
|
20
|
-
agent2 = get_agent(v)
|
|
21
|
-
w = 2
|
|
22
|
-
ec = "#e8e8e8"
|
|
23
|
-
if State.RESISTANT in (agent1.state, agent2.state):
|
|
24
|
-
w = 3
|
|
25
|
-
ec = "black"
|
|
26
|
-
edge_width.append(w)
|
|
27
|
-
edge_color.append(ec)
|
|
28
|
-
node_color_dict = {
|
|
29
|
-
State.INFECTED: "tab:red",
|
|
30
|
-
State.SUSCEPTIBLE: "tab:green",
|
|
31
|
-
State.RESISTANT: "tab:gray",
|
|
32
|
-
}
|
|
33
|
-
node_color = [node_color_dict[get_agent(node).state] for node in graph.nodes()]
|
|
34
|
-
return {
|
|
35
|
-
"width": edge_width,
|
|
36
|
-
"edge_color": edge_color,
|
|
37
|
-
"node_color": node_color,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def get_resistant_susceptible_ratio(model):
|
|
42
|
-
ratio = model.resistant_susceptible_ratio()
|
|
43
|
-
ratio_text = r"$\infty$" if ratio is math.inf else f"{ratio:.2f}"
|
|
44
|
-
infected_text = str(number_infected(model))
|
|
45
|
-
|
|
46
|
-
return f"Resistant/Susceptible Ratio: {ratio_text}<br>Infected Remaining: {infected_text}"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def make_plot(model):
|
|
50
|
-
# This is for the case when we want to plot multiple measures in 1 figure.
|
|
51
|
-
fig = Figure()
|
|
52
|
-
ax = fig.subplots()
|
|
53
|
-
measures = ["Infected", "Susceptible", "Resistant"]
|
|
54
|
-
colors = ["tab:red", "tab:green", "tab:gray"]
|
|
55
|
-
for i, m in enumerate(measures):
|
|
56
|
-
color = colors[i]
|
|
57
|
-
df = model.datacollector.get_model_vars_dataframe()
|
|
58
|
-
ax.plot(df.loc[:, m], label=m, color=color)
|
|
59
|
-
fig.legend()
|
|
60
|
-
# Set integer x axis
|
|
61
|
-
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
|
|
62
|
-
ax.set_xlabel("Step")
|
|
63
|
-
ax.set_ylabel("Number of Agents")
|
|
64
|
-
return solara.FigureMatplotlib(fig)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
model_params = {
|
|
68
|
-
"num_nodes": Slider(
|
|
69
|
-
label="Number of agents",
|
|
70
|
-
value=10,
|
|
71
|
-
min=10,
|
|
72
|
-
max=100,
|
|
73
|
-
step=1,
|
|
74
|
-
),
|
|
75
|
-
"avg_node_degree": Slider(
|
|
76
|
-
label="Avg Node Degree",
|
|
77
|
-
value=3,
|
|
78
|
-
min=3,
|
|
79
|
-
max=8,
|
|
80
|
-
step=1,
|
|
81
|
-
),
|
|
82
|
-
"initial_outbreak_size": Slider(
|
|
83
|
-
label="Initial Outbreak Size",
|
|
84
|
-
value=1,
|
|
85
|
-
min=1,
|
|
86
|
-
max=10,
|
|
87
|
-
step=1,
|
|
88
|
-
),
|
|
89
|
-
"virus_spread_chance": Slider(
|
|
90
|
-
label="Virus Spread Chance",
|
|
91
|
-
value=0.4,
|
|
92
|
-
min=0.0,
|
|
93
|
-
max=1.0,
|
|
94
|
-
step=0.1,
|
|
95
|
-
),
|
|
96
|
-
"virus_check_frequency": Slider(
|
|
97
|
-
label="Virus Check Frequency",
|
|
98
|
-
value=0.4,
|
|
99
|
-
min=0.0,
|
|
100
|
-
max=1.0,
|
|
101
|
-
step=0.1,
|
|
102
|
-
),
|
|
103
|
-
"recovery_chance": Slider(
|
|
104
|
-
label="Recovery Chance",
|
|
105
|
-
value=0.3,
|
|
106
|
-
min=0.0,
|
|
107
|
-
max=1.0,
|
|
108
|
-
step=0.1,
|
|
109
|
-
),
|
|
110
|
-
"gain_resistance_chance": Slider(
|
|
111
|
-
label="Gain Resistance Chance",
|
|
112
|
-
value=0.5,
|
|
113
|
-
min=0.0,
|
|
114
|
-
max=1.0,
|
|
115
|
-
step=0.1,
|
|
116
|
-
),
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
SpacePlot = make_space_matplotlib(agent_portrayal)
|
|
120
|
-
|
|
121
|
-
model1 = VirusOnNetwork()
|
|
122
|
-
|
|
123
|
-
page = SolaraViz(
|
|
124
|
-
model1,
|
|
125
|
-
[
|
|
126
|
-
SpacePlot,
|
|
127
|
-
make_plot,
|
|
128
|
-
# get_resistant_susceptible_ratio, # TODO: Fix and uncomment
|
|
129
|
-
],
|
|
130
|
-
model_params=model_params,
|
|
131
|
-
name="Virus Model",
|
|
132
|
-
)
|
|
133
|
-
page # noqa
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"project": "Example Project",
|
|
3
|
-
"snake": "{{ cookiecutter.project.lower().replace(' ', '_') }}",
|
|
4
|
-
"camel": "{{ cookiecutter.project.title().replace(' ', '') }}",
|
|
5
|
-
"agent": "{{ cookiecutter.camel + 'Agent'}}",
|
|
6
|
-
"model": "{{ cookiecutter.camel + 'Model'}}",
|
|
7
|
-
"description": "Example short description of the project"
|
|
8
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
"""helper module."""
|
|
2
|
-
|
|
3
|
-
import glob
|
|
4
|
-
import os
|
|
5
|
-
|
|
6
|
-
file_list = glob.glob("**/*.pytemplate", recursive=True)
|
|
7
|
-
|
|
8
|
-
for file_path in file_list:
|
|
9
|
-
# Check if the file is a regular file
|
|
10
|
-
if not os.path.isfile(file_path):
|
|
11
|
-
continue
|
|
12
|
-
# Rename the file
|
|
13
|
-
os.rename(file_path, file_path.replace(".pytemplate", ".py"))
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Configure visualization elements and instantiate a server
|
|
3
|
-
"""
|
|
4
|
-
from mesa.visualization import SolaraViz
|
|
5
|
-
|
|
6
|
-
from {{ cookiecutter.snake }}.model import {{ cookiecutter.model }}, {{ cookiecutter.agent }} # noqa
|
|
7
|
-
|
|
8
|
-
import mesa
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def circle_portrayal_example(agent):
|
|
12
|
-
return {
|
|
13
|
-
"size": 40,
|
|
14
|
-
# This is Matplotlib's color
|
|
15
|
-
"color": "tab:pink",
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
model_params = {"num_agents": 10, "width": 10, "height": 10}
|
|
20
|
-
|
|
21
|
-
page = SolaraViz(
|
|
22
|
-
{{cookiecutter.model}},
|
|
23
|
-
model_params,
|
|
24
|
-
measures=["num_agents"],
|
|
25
|
-
agent_portrayal=circle_portrayal_example
|
|
26
|
-
)
|
|
27
|
-
page # noqa
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"""helper modules."""
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import mesa
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class {{cookiecutter.agent}}(mesa.Agent): # noqa
|
|
5
|
-
"""
|
|
6
|
-
An agent
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
def __init__(self, unique_id, model):
|
|
10
|
-
"""
|
|
11
|
-
Customize the agent
|
|
12
|
-
"""
|
|
13
|
-
self.unique_id = unique_id
|
|
14
|
-
super().__init__(unique_id, model)
|
|
15
|
-
|
|
16
|
-
def step(self):
|
|
17
|
-
"""
|
|
18
|
-
Modify this method to change what an individual agent will do during each step.
|
|
19
|
-
Can include logic based on neighbors states.
|
|
20
|
-
"""
|
|
21
|
-
pass
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class {{cookiecutter.model}}(mesa.Model):
|
|
25
|
-
"""
|
|
26
|
-
The model class holds the model-level attributes, manages the agents, and generally handles
|
|
27
|
-
the global level of our model.
|
|
28
|
-
|
|
29
|
-
There is only one model-level parameter: how many agents the model contains. When a new model
|
|
30
|
-
is started, we want it to populate itself with the given number of agents.
|
|
31
|
-
|
|
32
|
-
The scheduler is a special model component which controls the order in which agents are activated.
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
def __init__(self, num_agents, width, height):
|
|
36
|
-
super().__init__()
|
|
37
|
-
self.num_agents = num_agents
|
|
38
|
-
self.schedule = mesa.time.RandomActivation(self)
|
|
39
|
-
self.grid = mesa.space.MultiGrid(width=width, height=height, torus=True)
|
|
40
|
-
|
|
41
|
-
for i in range(self.num_agents):
|
|
42
|
-
agent = {{cookiecutter.agent}}(i, self)
|
|
43
|
-
self.schedule.add(agent)
|
|
44
|
-
|
|
45
|
-
x = self.random.randrange(self.grid.width)
|
|
46
|
-
y = self.random.randrange(self.grid.height)
|
|
47
|
-
self.grid.place_agent(agent, (x, y))
|
|
48
|
-
|
|
49
|
-
# example data collector
|
|
50
|
-
self.datacollector = mesa.datacollection.DataCollector({"num_agents": "num_agents"})
|
|
51
|
-
|
|
52
|
-
self.running = True
|
|
53
|
-
self.datacollector.collect(self)
|
|
54
|
-
|
|
55
|
-
def step(self):
|
|
56
|
-
"""
|
|
57
|
-
A model step. Used for collecting data and advancing the schedule
|
|
58
|
-
"""
|
|
59
|
-
self.datacollector.collect(self)
|
|
60
|
-
self.schedule.step()
|
mesa/examples.py
DELETED
mesa/main.py
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
"""main module for running mesa models with a server."""
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import sys
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from subprocess import call
|
|
7
|
-
|
|
8
|
-
import click
|
|
9
|
-
|
|
10
|
-
from mesa import __version__
|
|
11
|
-
|
|
12
|
-
PROJECT_PATH = click.Path(
|
|
13
|
-
exists=True, file_okay=False, dir_okay=True, resolve_path=True
|
|
14
|
-
)
|
|
15
|
-
COOKIECUTTER_DIR = "mesa/cookiecutter-mesa"
|
|
16
|
-
SCRIPTS_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
17
|
-
COOKIECUTTER_PATH = os.path.join(os.path.dirname(SCRIPTS_DIR), COOKIECUTTER_DIR)
|
|
18
|
-
|
|
19
|
-
CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@click.group(context_settings=CONTEXT_SETTINGS)
|
|
23
|
-
def cli():
|
|
24
|
-
"""Manage Mesa projects."""
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@cli.command()
|
|
28
|
-
@click.argument("project", type=PROJECT_PATH, default=".")
|
|
29
|
-
def runserver(project):
|
|
30
|
-
"""Run mesa project PROJECT.
|
|
31
|
-
|
|
32
|
-
PROJECT is the path to the directory containing `run.py`, or the current
|
|
33
|
-
directory if not specified.
|
|
34
|
-
"""
|
|
35
|
-
run_files = ["run.py", "server.py"]
|
|
36
|
-
for run_file in run_files:
|
|
37
|
-
run_path = Path(project) / run_file
|
|
38
|
-
if not run_path.exists():
|
|
39
|
-
continue
|
|
40
|
-
args = [sys.executable, str(run_path)]
|
|
41
|
-
call(args)
|
|
42
|
-
sys.exit(f"ERROR: file run.py or server.py (in {Path(project)}) does not exist")
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@click.command()
|
|
46
|
-
@click.option(
|
|
47
|
-
"--no-input", is_flag=True, help="Do not prompt user for custom mesa model input."
|
|
48
|
-
)
|
|
49
|
-
def startproject(no_input):
|
|
50
|
-
"""Create a new mesa project."""
|
|
51
|
-
args = ["cookiecutter", COOKIECUTTER_PATH]
|
|
52
|
-
if no_input:
|
|
53
|
-
args.append("--no-input")
|
|
54
|
-
call(args)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@click.command()
|
|
58
|
-
def version():
|
|
59
|
-
"""Show the version of mesa."""
|
|
60
|
-
print(f"mesa {__version__}")
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
cli.add_command(runserver)
|
|
64
|
-
cli.add_command(startproject)
|
|
65
|
-
cli.add_command(version)
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"""Altair based solara components for visualization mesa spaces."""
|
|
2
|
-
|
|
3
|
-
import contextlib
|
|
4
|
-
|
|
5
|
-
import solara
|
|
6
|
-
|
|
7
|
-
with contextlib.suppress(ImportError):
|
|
8
|
-
import altair as alt
|
|
9
|
-
|
|
10
|
-
from mesa.visualization.utils import update_counter
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def make_space_altair(agent_portrayal=None): # noqa: D103
|
|
14
|
-
if agent_portrayal is None:
|
|
15
|
-
|
|
16
|
-
def agent_portrayal(a):
|
|
17
|
-
return {"id": a.unique_id}
|
|
18
|
-
|
|
19
|
-
def MakeSpaceAltair(model):
|
|
20
|
-
return SpaceAltair(model, agent_portrayal)
|
|
21
|
-
|
|
22
|
-
return MakeSpaceAltair
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@solara.component
|
|
26
|
-
def SpaceAltair(model, agent_portrayal, dependencies: list[any] | None = None): # noqa: D103
|
|
27
|
-
update_counter.get()
|
|
28
|
-
space = getattr(model, "grid", None)
|
|
29
|
-
if space is None:
|
|
30
|
-
# Sometimes the space is defined as model.space instead of model.grid
|
|
31
|
-
space = model.space
|
|
32
|
-
chart = _draw_grid(space, agent_portrayal)
|
|
33
|
-
solara.FigureAltair(chart)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def _draw_grid(space, agent_portrayal):
|
|
37
|
-
def portray(g):
|
|
38
|
-
all_agent_data = []
|
|
39
|
-
for content, (x, y) in g.coord_iter():
|
|
40
|
-
if not content:
|
|
41
|
-
continue
|
|
42
|
-
if not hasattr(content, "__iter__"):
|
|
43
|
-
# Is a single grid
|
|
44
|
-
content = [content] # noqa: PLW2901
|
|
45
|
-
for agent in content:
|
|
46
|
-
# use all data from agent portrayal, and add x,y coordinates
|
|
47
|
-
agent_data = agent_portrayal(agent)
|
|
48
|
-
agent_data["x"] = x
|
|
49
|
-
agent_data["y"] = y
|
|
50
|
-
all_agent_data.append(agent_data)
|
|
51
|
-
return all_agent_data
|
|
52
|
-
|
|
53
|
-
all_agent_data = portray(space)
|
|
54
|
-
invalid_tooltips = ["color", "size", "x", "y"]
|
|
55
|
-
|
|
56
|
-
encoding_dict = {
|
|
57
|
-
# no x-axis label
|
|
58
|
-
"x": alt.X("x", axis=None, type="ordinal"),
|
|
59
|
-
# no y-axis label
|
|
60
|
-
"y": alt.Y("y", axis=None, type="ordinal"),
|
|
61
|
-
"tooltip": [
|
|
62
|
-
alt.Tooltip(key, type=alt.utils.infer_vegalite_type([value]))
|
|
63
|
-
for key, value in all_agent_data[0].items()
|
|
64
|
-
if key not in invalid_tooltips
|
|
65
|
-
],
|
|
66
|
-
}
|
|
67
|
-
has_color = "color" in all_agent_data[0]
|
|
68
|
-
if has_color:
|
|
69
|
-
encoding_dict["color"] = alt.Color("color", type="nominal")
|
|
70
|
-
has_size = "size" in all_agent_data[0]
|
|
71
|
-
if has_size:
|
|
72
|
-
encoding_dict["size"] = alt.Size("size", type="quantitative")
|
|
73
|
-
|
|
74
|
-
chart = (
|
|
75
|
-
alt.Chart(
|
|
76
|
-
alt.Data(values=all_agent_data), encoding=alt.Encoding(**encoding_dict)
|
|
77
|
-
)
|
|
78
|
-
.mark_point(filled=True)
|
|
79
|
-
.properties(width=280, height=280)
|
|
80
|
-
# .configure_view(strokeOpacity=0) # hide grid/chart lines
|
|
81
|
-
)
|
|
82
|
-
# This is the default value for the marker size, which auto-scales
|
|
83
|
-
# according to the grid area.
|
|
84
|
-
if not has_size:
|
|
85
|
-
length = min(space.width, space.height)
|
|
86
|
-
chart = chart.mark_point(size=30000 / length**2, filled=True)
|
|
87
|
-
|
|
88
|
-
return chart
|