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.

Files changed (111) hide show
  1. mesa/__init__.py +1 -3
  2. mesa/agent.py +23 -8
  3. mesa/batchrunner.py +26 -1
  4. {examples → mesa/examples}/README.md +11 -11
  5. mesa/examples/__init__.py +21 -0
  6. {examples → mesa/examples}/advanced/epstein_civil_violence/Readme.md +3 -2
  7. examples/advanced/epstein_civil_violence/epstein_civil_violence/agent.py → mesa/examples/advanced/epstein_civil_violence/agents.py +44 -38
  8. mesa/examples/advanced/epstein_civil_violence/app.py +73 -0
  9. mesa/examples/advanced/epstein_civil_violence/model.py +114 -0
  10. examples/advanced/pd_grid/readme.md → mesa/examples/advanced/pd_grid/Readme.md +4 -3
  11. mesa/examples/advanced/pd_grid/app.py +54 -0
  12. {examples/advanced/pd_grid → mesa/examples/advanced}/pd_grid/model.py +1 -2
  13. {examples → mesa/examples}/advanced/sugarscape_g1mt/Readme.md +6 -29
  14. examples/advanced/sugarscape_g1mt/sugarscape_g1mt/trader_agents.py → mesa/examples/advanced/sugarscape_g1mt/agents.py +26 -3
  15. {examples → mesa/examples}/advanced/sugarscape_g1mt/app.py +19 -18
  16. {examples/advanced/sugarscape_g1mt → mesa/examples/advanced}/sugarscape_g1mt/model.py +6 -6
  17. {examples → mesa/examples}/advanced/sugarscape_g1mt/tests.py +3 -6
  18. mesa/examples/advanced/wolf_sheep/app.py +84 -0
  19. {examples/advanced/wolf_sheep → mesa/examples/advanced}/wolf_sheep/model.py +9 -8
  20. mesa/examples/basic/boid_flockers/Readme.md +22 -0
  21. {examples → mesa/examples}/basic/boid_flockers/app.py +3 -4
  22. {examples → mesa/examples}/basic/boid_flockers/model.py +1 -2
  23. {examples → mesa/examples}/basic/boltzmann_wealth_model/Readme.md +1 -5
  24. mesa/examples/basic/boltzmann_wealth_model/__init__.py +0 -0
  25. {examples → mesa/examples}/basic/boltzmann_wealth_model/app.py +15 -12
  26. {examples → mesa/examples}/basic/boltzmann_wealth_model/model.py +3 -4
  27. {examples → mesa/examples}/basic/conways_game_of_life/Readme.md +11 -7
  28. mesa/examples/basic/conways_game_of_life/__init__.py +0 -0
  29. {examples → mesa/examples}/basic/conways_game_of_life/agents.py +8 -8
  30. mesa/examples/basic/conways_game_of_life/app.py +51 -0
  31. {examples → mesa/examples}/basic/conways_game_of_life/model.py +3 -4
  32. {examples → mesa/examples}/basic/conways_game_of_life/st_app.py +2 -1
  33. examples/basic/schelling/README.md → mesa/examples/basic/schelling/Readme.md +2 -9
  34. mesa/examples/basic/schelling/__init__.py +0 -0
  35. {examples → mesa/examples}/basic/schelling/app.py +6 -7
  36. {examples → mesa/examples}/basic/schelling/model.py +1 -2
  37. mesa/examples/basic/virus_on_network/__init__.py +0 -0
  38. mesa/examples/basic/virus_on_network/app.py +114 -0
  39. {examples → mesa/examples}/basic/virus_on_network/model.py +4 -7
  40. mesa/experimental/cell_space/discrete_space.py +6 -0
  41. mesa/experimental/devs/eventlist.py +6 -0
  42. mesa/model.py +13 -0
  43. mesa/space.py +70 -35
  44. mesa/visualization/__init__.py +16 -5
  45. mesa/visualization/components/__init__.py +83 -0
  46. mesa/visualization/components/altair_components.py +188 -0
  47. mesa/visualization/components/matplotlib_components.py +176 -0
  48. mesa/visualization/mpl_space_drawing.py +558 -0
  49. mesa/visualization/solara_viz.py +30 -20
  50. {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/METADATA +1 -3
  51. mesa-3.0.0rc0.dist-info/RECORD +95 -0
  52. examples/advanced/epstein_civil_violence/epstein_civil_violence/model.py +0 -146
  53. examples/advanced/epstein_civil_violence/epstein_civil_violence/portrayal.py +0 -33
  54. examples/advanced/epstein_civil_violence/epstein_civil_violence/server.py +0 -81
  55. examples/advanced/epstein_civil_violence/requirements.txt +0 -3
  56. examples/advanced/epstein_civil_violence/run.py +0 -3
  57. examples/advanced/pd_grid/pd_grid/portrayal.py +0 -19
  58. examples/advanced/pd_grid/pd_grid/server.py +0 -21
  59. examples/advanced/pd_grid/requirements.txt +0 -3
  60. examples/advanced/pd_grid/run.py +0 -3
  61. examples/advanced/sugarscape_g1mt/requirements.txt +0 -6
  62. examples/advanced/sugarscape_g1mt/run.py +0 -105
  63. examples/advanced/sugarscape_g1mt/sugarscape_g1mt/resource_agents.py +0 -26
  64. examples/advanced/sugarscape_g1mt/sugarscape_g1mt/server.py +0 -61
  65. examples/advanced/wolf_sheep/requirements.txt +0 -1
  66. examples/advanced/wolf_sheep/run.py +0 -3
  67. examples/advanced/wolf_sheep/wolf_sheep/resources/sheep.png +0 -0
  68. examples/advanced/wolf_sheep/wolf_sheep/resources/wolf.png +0 -0
  69. examples/advanced/wolf_sheep/wolf_sheep/server.py +0 -78
  70. examples/basic/__init__.py +0 -13
  71. examples/basic/boid_flockers/Readme.md +0 -43
  72. examples/basic/conways_game_of_life/portrayal.py +0 -18
  73. examples/basic/conways_game_of_life/requirements.txt +0 -1
  74. examples/basic/conways_game_of_life/server.py +0 -11
  75. examples/basic/virus_on_network/app.py +0 -133
  76. mesa/cookiecutter-mesa/cookiecutter.json +0 -8
  77. mesa/cookiecutter-mesa/hooks/post_gen_project.py +0 -13
  78. mesa/cookiecutter-mesa/{{cookiecutter.snake}}/README.md +0 -4
  79. mesa/cookiecutter-mesa/{{cookiecutter.snake}}/app.pytemplate +0 -27
  80. mesa/cookiecutter-mesa/{{cookiecutter.snake}}/setup.pytemplate +0 -11
  81. mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/__init__.py +0 -1
  82. mesa/cookiecutter-mesa/{{cookiecutter.snake}}/{{cookiecutter.snake}}/model.pytemplate +0 -60
  83. mesa/examples.py +0 -3
  84. mesa/main.py +0 -65
  85. mesa/visualization/components/altair.py +0 -88
  86. mesa/visualization/components/matplotlib.py +0 -342
  87. mesa-3.0.0b1.dist-info/RECORD +0 -114
  88. {examples → mesa/examples/advanced}/__init__.py +0 -0
  89. {examples → mesa/examples}/advanced/epstein_civil_violence/Epstein Civil Violence.ipynb +0 -0
  90. {examples/advanced → mesa/examples/advanced/epstein_civil_violence}/__init__.py +0 -0
  91. {examples/advanced/epstein_civil_violence/epstein_civil_violence → mesa/examples/advanced/pd_grid}/__init__.py +0 -0
  92. /examples/advanced/pd_grid/pd_grid/agent.py → /mesa/examples/advanced/pd_grid/agents.py +0 -0
  93. {examples → mesa/examples}/advanced/pd_grid/analysis.ipynb +0 -0
  94. {examples/advanced/pd_grid/pd_grid → mesa/examples/advanced/sugarscape_g1mt}/__init__.py +0 -0
  95. {examples/advanced/sugarscape_g1mt → mesa/examples/advanced}/sugarscape_g1mt/sugar-map.txt +0 -0
  96. {examples → mesa/examples}/advanced/wolf_sheep/Readme.md +0 -0
  97. {examples/advanced/sugarscape_g1mt/sugarscape_g1mt → mesa/examples/advanced/wolf_sheep}/__init__.py +0 -0
  98. {examples/advanced/wolf_sheep → mesa/examples/advanced}/wolf_sheep/agents.py +0 -0
  99. {examples/advanced/wolf_sheep → mesa/examples/basic}/__init__.py +0 -0
  100. {examples/advanced/wolf_sheep/wolf_sheep → mesa/examples/basic/boid_flockers}/__init__.py +0 -0
  101. {examples → mesa/examples}/basic/boid_flockers/agents.py +0 -0
  102. {examples → mesa/examples}/basic/boltzmann_wealth_model/agents.py +0 -0
  103. {examples → mesa/examples}/basic/boltzmann_wealth_model/st_app.py +0 -0
  104. {examples → mesa/examples}/basic/schelling/agents.py +0 -0
  105. {examples → mesa/examples}/basic/schelling/analysis.ipynb +0 -0
  106. /examples/basic/virus_on_network/README.md → /mesa/examples/basic/virus_on_network/Readme.md +0 -0
  107. {examples → mesa/examples}/basic/virus_on_network/agents.py +0 -0
  108. {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/WHEEL +0 -0
  109. {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/entry_points.txt +0 -0
  110. {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/licenses/LICENSE +0 -0
  111. {mesa-3.0.0b1.dist-info → mesa-3.0.0rc0.dist-info}/licenses/NOTICE +0 -0
@@ -34,51 +34,28 @@ cross over one another otherwise *end*.
34
34
  (Epstein and Axtell, 1996, p. 105)
35
35
 
36
36
  The model demonstrates several Mesa concepts and features:
37
- - MultiGrid
37
+ - OrthogonalMooreGrid
38
38
  - Multiple agent types (traders, sugar, spice)
39
39
  - Dynamically removing agents from the grid and schedule when they die
40
40
  - Data Collection at the model and agent level
41
- - Batchrunner (i.e. parameter sweeps)
41
+ - custom solara matplotlib space visualization
42
42
 
43
- ## Installation
44
-
45
- To install the dependencies use pip and the requirements.txt in this directory. e.g.
46
-
47
- ```
48
- $ pip install -r requirements.txt
49
- ```
50
43
 
51
44
  ## How to Run
52
-
53
- To run the model a single instance of the model:
54
-
55
- ```
56
- $ python run.py -s
57
- ```
58
-
59
- To run the model with BatchRunner:
60
-
61
- ```
62
- $ python run.py -b
63
- ```
64
-
65
45
  To run the model interactively:
66
46
 
67
47
  ```
68
- $ mesa runserver
48
+ $ solara run app.py
69
49
  ```
70
50
 
71
51
  Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press Reset, then Run.
72
52
 
73
53
  ## Files
74
54
 
75
- * `sugarscape_g1mt/trader_agents.py`: Defines the Trader agent class.
76
- * `sugarscape_g1mt/resource_agents.py`: Defines the Resource agent class which contains an amount of sugar and spice.
77
- * `sugarscape_g1mt/model.py`: Manages the Sugarscape Constant Growback with Traders model.
78
- * `sugarscape_g1mt/sugar_map.txt`: Provides sugar and spice landscape in raster type format.
79
- * `server.py`: Sets up an interactive visualization server.
80
- * `run.py`: Runs Server, Single Run or Batch Run with data collection and basic analysis.
55
+ * `model.py`: The Sugarscape Constant Growback with Traders model.
56
+ * `agents.py`: Defines the Trader agent class and the Resource agent class which contains an amount of sugar and spice.
81
57
  * `app.py`: Runs a visualization server via Solara (`solara run app.py`).
58
+ * `sugar_map.txt`: Provides sugar and spice landscape in raster type format.
82
59
  * `tests.py`: Has tests to ensure that the model reproduces the results in shown in Growing Artificial Societies.
83
60
 
84
61
  ## Additional Resources
@@ -1,8 +1,6 @@
1
1
  import math
2
2
 
3
- from mesa.experimental.cell_space import CellAgent
4
-
5
- from .resource_agents import Resource
3
+ from mesa.experimental.cell_space import CellAgent, FixedAgent
6
4
 
7
5
 
8
6
  # Helper function
@@ -20,6 +18,31 @@ def get_distance(cell_1, cell_2):
20
18
  return math.sqrt(dx**2 + dy**2)
21
19
 
22
20
 
21
+ class Resource(FixedAgent):
22
+ """
23
+ Resource:
24
+ - contains an amount of sugar and spice
25
+ - grows 1 amount of sugar at each turn
26
+ - grows 1 amount of spice at each turn
27
+ """
28
+
29
+ def __init__(self, model, max_sugar, max_spice, cell):
30
+ super().__init__(model)
31
+ self.sugar_amount = max_sugar
32
+ self.max_sugar = max_sugar
33
+ self.spice_amount = max_spice
34
+ self.max_spice = max_spice
35
+ self.cell = cell
36
+
37
+ def step(self):
38
+ """
39
+ Growth function, adds one unit of sugar and spice each step up to
40
+ max amount
41
+ """
42
+ self.sugar_amount = min([self.max_sugar, self.sugar_amount + 1])
43
+ self.spice_amount = min([self.max_spice, self.spice_amount + 1])
44
+
45
+
23
46
  class Trader(CellAgent):
24
47
  """
25
48
  Trader:
@@ -1,9 +1,10 @@
1
1
  import numpy as np
2
2
  import solara
3
3
  from matplotlib.figure import Figure
4
- from mesa.visualization import SolaraViz, make_plot_measure
5
- from sugarscape_g1mt.model import SugarscapeG1mt
6
- from sugarscape_g1mt.trader_agents import Trader
4
+
5
+ from mesa.examples.advanced.sugarscape_g1mt.agents import Trader
6
+ from mesa.examples.advanced.sugarscape_g1mt.model import SugarscapeG1mt
7
+ from mesa.visualization import SolaraViz, make_plot_component
7
8
 
8
9
 
9
10
  def SpaceDrawer(model):
@@ -14,19 +15,19 @@ def SpaceDrawer(model):
14
15
  "trader": {"x": [], "y": [], "c": "tab:red", "marker": "o", "s": 10},
15
16
  }
16
17
 
17
- for content, (i, j) in g.coord_iter():
18
- for agent in content:
19
- if isinstance(agent, Trader):
20
- layers["trader"]["x"].append(i)
21
- layers["trader"]["y"].append(j)
22
- else:
23
- # Don't visualize resource with value <= 1.
24
- layers["sugar"][i][j] = (
25
- agent.sugar_amount if agent.sugar_amount > 1 else np.nan
26
- )
27
- layers["spice"][i][j] = (
28
- agent.spice_amount if agent.spice_amount > 1 else np.nan
29
- )
18
+ for agent in g.all_cells.agents:
19
+ i, j = agent.cell.coordinate
20
+ if isinstance(agent, Trader):
21
+ layers["trader"]["x"].append(i)
22
+ layers["trader"]["y"].append(j)
23
+ else:
24
+ # Don't visualize resource with value <= 1.
25
+ layers["sugar"][i][j] = (
26
+ agent.sugar_amount if agent.sugar_amount > 1 else np.nan
27
+ )
28
+ layers["spice"][i][j] = (
29
+ agent.spice_amount if agent.spice_amount > 1 else np.nan
30
+ )
30
31
  return layers
31
32
 
32
33
  fig = Figure()
@@ -54,8 +55,8 @@ model1 = SugarscapeG1mt(50, 50)
54
55
 
55
56
  page = SolaraViz(
56
57
  model1,
57
- components=[SpaceDrawer, make_plot_measure(["Trader", "Price"])],
58
+ components=[SpaceDrawer, make_plot_component(["Trader", "Price"])],
58
59
  name="Sugarscape {G1, M, T}",
59
- play_interval=1500,
60
+ play_interval=150,
60
61
  )
61
62
  page # noqa
@@ -1,11 +1,10 @@
1
1
  from pathlib import Path
2
2
 
3
- import mesa
4
3
  import numpy as np
5
- from mesa.experimental.cell_space import OrthogonalVonNeumannGrid
6
4
 
7
- from .resource_agents import Resource
8
- from .trader_agents import Trader
5
+ import mesa
6
+ from mesa.examples.advanced.sugarscape_g1mt.agents import Resource, Trader
7
+ from mesa.experimental.cell_space import OrthogonalVonNeumannGrid
9
8
 
10
9
 
11
10
  # Helper Functions
@@ -53,8 +52,9 @@ class SugarscapeG1mt(mesa.Model):
53
52
  vision_min=1,
54
53
  vision_max=5,
55
54
  enable_trade=True,
55
+ seed=None,
56
56
  ):
57
- super().__init__()
57
+ super().__init__(seed=seed)
58
58
  # Initiate width and height of sugarscape
59
59
  self.width = width
60
60
  self.height = height
@@ -176,5 +176,5 @@ class SugarscapeG1mt(mesa.Model):
176
176
  self.datacollector._agent_records[self.steps] = agent_trades
177
177
 
178
178
  def run_model(self, step_count=1000):
179
- for i in range(step_count):
179
+ for _ in range(step_count):
180
180
  self.step()
@@ -1,11 +1,8 @@
1
- import random
2
-
3
1
  import numpy as np
4
2
  from scipy import stats
5
- from sugarscape_g1mt.model import SugarscapeG1mt, flatten
6
- from sugarscape_g1mt.trader_agents import Trader
7
3
 
8
- random.seed(1)
4
+ from .agents import Trader
5
+ from .model import SugarscapeG1mt, flatten
9
6
 
10
7
 
11
8
  def check_slope(y, increasing):
@@ -19,7 +16,7 @@ def check_slope(y, increasing):
19
16
  def test_decreasing_price_variance():
20
17
  # The variance of the average trade price should decrease over time (figure IV-3)
21
18
  # See Growing Artificial Societies p. 109.
22
- model = SugarscapeG1mt()
19
+ model = SugarscapeG1mt(42)
23
20
  model.datacollector._new_model_reporter(
24
21
  "price_variance",
25
22
  lambda m: np.var(
@@ -0,0 +1,84 @@
1
+ from mesa.examples.advanced.wolf_sheep.agents import GrassPatch, Sheep, Wolf
2
+ from mesa.examples.advanced.wolf_sheep.model import WolfSheep
3
+ from mesa.visualization import (
4
+ Slider,
5
+ SolaraViz,
6
+ make_plot_component,
7
+ make_space_component,
8
+ )
9
+
10
+
11
+ def wolf_sheep_portrayal(agent):
12
+ if agent is None:
13
+ return
14
+
15
+ portrayal = {
16
+ "size": 25,
17
+ }
18
+
19
+ if isinstance(agent, Wolf):
20
+ portrayal["color"] = "tab:red"
21
+ portrayal["marker"] = "o"
22
+ portrayal["zorder"] = 2
23
+ elif isinstance(agent, Sheep):
24
+ portrayal["color"] = "tab:cyan"
25
+ portrayal["marker"] = "o"
26
+ portrayal["zorder"] = 2
27
+ elif isinstance(agent, GrassPatch):
28
+ if agent.fully_grown:
29
+ portrayal["color"] = "tab:green"
30
+ else:
31
+ portrayal["color"] = "tab:brown"
32
+ portrayal["marker"] = "s"
33
+ portrayal["size"] = 75
34
+
35
+ return portrayal
36
+
37
+
38
+ model_params = {
39
+ # The following line is an example to showcase StaticText.
40
+ "grass": {
41
+ "type": "Select",
42
+ "value": True,
43
+ "values": [True, False],
44
+ "label": "grass regrowth enabled?",
45
+ },
46
+ "grass_regrowth_time": Slider("Grass Regrowth Time", 20, 1, 50),
47
+ "initial_sheep": Slider("Initial Sheep Population", 100, 10, 300),
48
+ "sheep_reproduce": Slider("Sheep Reproduction Rate", 0.04, 0.01, 1.0, 0.01),
49
+ "initial_wolves": Slider("Initial Wolf Population", 10, 5, 100),
50
+ "wolf_reproduce": Slider(
51
+ "Wolf Reproduction Rate",
52
+ 0.05,
53
+ 0.01,
54
+ 1.0,
55
+ 0.01,
56
+ ),
57
+ "wolf_gain_from_food": Slider("Wolf Gain From Food Rate", 20, 1, 50),
58
+ "sheep_gain_from_food": Slider("Sheep Gain From Food", 4, 1, 10),
59
+ }
60
+
61
+
62
+ def post_process(ax):
63
+ ax.set_aspect("equal")
64
+ ax.set_xticks([])
65
+ ax.set_yticks([])
66
+
67
+
68
+ space_component = make_space_component(
69
+ wolf_sheep_portrayal, draw_grid=False, post_process=post_process
70
+ )
71
+ lineplot_component = make_plot_component(
72
+ {"Wolves": "tab:orange", "Sheep": "tab:cyan", "Grass": "tab:green"}
73
+ )
74
+
75
+ model = WolfSheep(grass=True)
76
+
77
+
78
+ page = SolaraViz(
79
+ model,
80
+ components=[space_component, lineplot_component],
81
+ model_params=model_params,
82
+ name="Wolf Sheep",
83
+ )
84
+ page # noqa
@@ -10,10 +10,9 @@ Replication of the model found in NetLogo:
10
10
  """
11
11
 
12
12
  import mesa
13
+ from mesa.examples.advanced.wolf_sheep.agents import GrassPatch, Sheep, Wolf
13
14
  from mesa.experimental.cell_space import OrthogonalMooreGrid
14
15
 
15
- from .agents import GrassPatch, Sheep, Wolf
16
-
17
16
 
18
17
  class WolfSheep(mesa.Model):
19
18
  """
@@ -67,7 +66,7 @@ class WolfSheep(mesa.Model):
67
66
  once it is eaten
68
67
  sheep_gain_from_food: Energy sheep gain from grass, if enabled.
69
68
  """
70
- super().__init__(seed=None)
69
+ super().__init__(seed=seed)
71
70
  # Set parameters
72
71
  self.width = width
73
72
  self.height = height
@@ -81,15 +80,17 @@ class WolfSheep(mesa.Model):
81
80
  collectors = {
82
81
  "Wolves": lambda m: len(m.agents_by_type[Wolf]),
83
82
  "Sheep": lambda m: len(m.agents_by_type[Sheep]),
83
+ "Grass": lambda m: len(
84
+ m.agents_by_type[GrassPatch].select(lambda a: a.fully_grown)
85
+ )
86
+ if m.grass
87
+ else -1,
84
88
  }
85
89
 
86
- if grass:
87
- collectors["Grass"] = lambda m: len(m.agents_by_type[GrassPatch])
88
-
89
90
  self.datacollector = mesa.DataCollector(collectors)
90
91
 
91
92
  # Create sheep:
92
- for i in range(self.initial_sheep):
93
+ for _ in range(self.initial_sheep):
93
94
  x = self.random.randrange(self.width)
94
95
  y = self.random.randrange(self.height)
95
96
  energy = self.random.randrange(2 * self.sheep_gain_from_food)
@@ -132,5 +133,5 @@ class WolfSheep(mesa.Model):
132
133
  self.datacollector.collect(self)
133
134
 
134
135
  def run_model(self, step_count=200):
135
- for i in range(step_count):
136
+ for _ in range(step_count):
136
137
  self.step()
@@ -0,0 +1,22 @@
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.
8
+
9
+ ## How to Run
10
+
11
+ * To launch the visualization interactively, run ``solara run app.py`` in this directory.It will automatically open a browser page.
12
+
13
+ ## Files
14
+
15
+ * [model.py](model.py): Ccntains the Boid Model
16
+ * [agents.py](agents.py): Contains the Boid agent
17
+ * [app.py](app.py): Solara based Visualization code.
18
+
19
+ ## Further Reading
20
+
21
+ The following link can be visited for more information on the boid flockers model:
22
+ https://cs.stanford.edu/people/eroberts/courses/soco/projects/2008-09/modeling-natural-systems/boids.html
@@ -1,6 +1,5 @@
1
- from mesa.visualization import Slider, SolaraViz, make_space_matplotlib
2
-
3
- from .model import BoidFlockers
1
+ from mesa.examples.basic.boid_flockers.model import BoidFlockers
2
+ from mesa.visualization import Slider, SolaraViz, make_space_component
4
3
 
5
4
 
6
5
  def boid_draw(agent):
@@ -52,7 +51,7 @@ model = BoidFlockers()
52
51
 
53
52
  page = SolaraViz(
54
53
  model,
55
- [make_space_matplotlib(agent_portrayal=boid_draw)],
54
+ [make_space_component(agent_portrayal=boid_draw, backend="matplotlib")],
56
55
  model_params=model_params,
57
56
  name="Boid Flocking Model",
58
57
  )
@@ -7,8 +7,7 @@ Uses numpy arrays to represent vectors.
7
7
  import numpy as np
8
8
 
9
9
  import mesa
10
-
11
- from .agents import Boid
10
+ from mesa.examples.basic.boid_flockers.agents import Boid
12
11
 
13
12
 
14
13
  class BoidFlockers(mesa.Model):
@@ -12,11 +12,6 @@ As the model runs, the distribution of wealth among agents goes from being perfe
12
12
 
13
13
  To follow the tutorial example, launch the Jupyter Notebook and run the code in ``Introduction to Mesa Tutorial Code.ipynb`` which you can find in the main mesa repo [here](https://github.com/projectmesa/mesa/blob/main/docs/tutorials/intro_tutorial.ipynb)
14
14
 
15
- Make sure to install the requirements first:
16
-
17
- ```
18
- $ pip install -r requirements.txt
19
- ```
20
15
 
21
16
  To launch the interactive server, as described in the [last section of the tutorial](https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html#adding-visualization), run:
22
17
 
@@ -30,6 +25,7 @@ If your browser doesn't open automatically, point it to [http://127.0.0.1:8765/]
30
25
  ## Files
31
26
 
32
27
  * ``model.py``: Final version of the model.
28
+ * ``agents.py``: Final version of the agent.
33
29
  * ``app.py``: Code for the interactive visualization.
34
30
 
35
31
  ## Optional
File without changes
@@ -1,19 +1,14 @@
1
+ from mesa.examples.basic.boltzmann_wealth_model.model import BoltzmannWealthModel
1
2
  from mesa.visualization import (
2
3
  SolaraViz,
3
- make_plot_measure,
4
- make_space_matplotlib,
4
+ make_plot_component,
5
+ make_space_component,
5
6
  )
6
7
 
7
- from .model import BoltzmannWealthModel
8
-
9
8
 
10
9
  def agent_portrayal(agent):
11
- size = 10
12
- color = "tab:red"
13
- if agent.wealth > 0:
14
- size = 50
15
- color = "tab:blue"
16
- return {"size": size, "color": color}
10
+ color = agent.wealth # we are using a colormap to translate wealth to color
11
+ return {"color": color}
17
12
 
18
13
 
19
14
  model_params = {
@@ -29,6 +24,11 @@ model_params = {
29
24
  "height": 10,
30
25
  }
31
26
 
27
+
28
+ def post_process(ax):
29
+ ax.get_figure().colorbar(ax.collections[0], label="wealth", ax=ax)
30
+
31
+
32
32
  # Create initial model instance
33
33
  model1 = BoltzmannWealthModel(50, 10, 10)
34
34
 
@@ -37,8 +37,11 @@ model1 = BoltzmannWealthModel(50, 10, 10)
37
37
  # Under the hood these are just classes that receive the model instance.
38
38
  # You can also author your own visualization elements, which can also be functions
39
39
  # that receive the model instance and return a valid solara component.
40
- SpaceGraph = make_space_matplotlib(agent_portrayal)
41
- GiniPlot = make_plot_measure("Gini")
40
+
41
+ SpaceGraph = make_space_component(
42
+ agent_portrayal, cmap="viridis", vmin=0, vmax=10, post_process=post_process
43
+ )
44
+ GiniPlot = make_plot_component("Gini")
42
45
 
43
46
  # Create the SolaraViz page. This will automatically create a server and display the
44
47
  # visualization elements in a web browser.
@@ -1,6 +1,5 @@
1
1
  import mesa
2
-
3
- from .agents import MoneyAgent
2
+ from mesa.examples.basic.boltzmann_wealth_model.agents import MoneyAgent
4
3
 
5
4
 
6
5
  class BoltzmannWealthModel(mesa.Model):
@@ -11,8 +10,8 @@ class BoltzmannWealthModel(mesa.Model):
11
10
  highly skewed distribution of wealth.
12
11
  """
13
12
 
14
- def __init__(self, n=100, width=10, height=10):
15
- super().__init__()
13
+ def __init__(self, n=100, width=10, height=10, seed=None):
14
+ super().__init__(seed=seed)
16
15
  self.num_agents = n
17
16
  self.grid = mesa.space.MultiGrid(width, height, True)
18
17
 
@@ -9,26 +9,30 @@ The "game" is a zero-player game, meaning that its evolution is determined by it
9
9
 
10
10
  ## How to Run
11
11
 
12
- To run the model interactively, run ``mesa runserver`` in this directory. e.g.
12
+ To run the model interactively you can use either the streamlit or solara version. For solara, you use
13
13
 
14
14
  ```
15
- $ mesa runserver
15
+ $ solara run app.py
16
16
  ```
17
17
 
18
- Then open your browser to [http://127.0.0.1:8521/](http://127.0.0.1:8521/) and press ``run``.
18
+ For streamlit, you need
19
+
20
+ ```
21
+ $ streamlit run st_app.py
22
+ ```
23
+
24
+ This will open your browser and show you the controls. You can start the model by hitting the run button.
19
25
 
20
26
  ## Files
21
27
 
22
28
  * ``agents.py``: Defines the behavior of an individual cell, which can be in two states: DEAD or ALIVE.
23
29
  * ``model.py``: Defines the model itself, initialized with a random configuration of alive and dead cells.
24
- * ``portrayal.py``: Describes for the front end how to render a cell.
30
+ * ``app.py``: Defines an interactive visualization using solara.
25
31
  * ``st_app.py``: Defines an interactive visualization using Streamlit.
26
32
 
27
33
  ## Optional
28
34
 
29
- * ``conways_game_of_life/st_app.py``: can be used to run the simulation via the streamlit interface.
30
- * For this some additional packages like ``streamlit`` and ``altair`` needs to be installed.
31
- * Once installed, the app can be opened in the browser using : ``streamlit run st_app.py``
35
+ * For the streamlit version, you need to have streamlit installed (can be done via pip install streamlit)
32
36
 
33
37
 
34
38
  ## Further Reading
File without changes
@@ -12,10 +12,10 @@ class Cell(Agent):
12
12
  super().__init__(model)
13
13
  self.x, self.y = pos
14
14
  self.state = init_state
15
- self._nextState = None
15
+ self._next_state = None
16
16
 
17
17
  @property
18
- def isAlive(self):
18
+ def is_alive(self):
19
19
  return self.state == self.ALIVE
20
20
 
21
21
  @property
@@ -31,17 +31,17 @@ class Cell(Agent):
31
31
  """
32
32
  # Get the neighbors and apply the rules on whether to be alive or dead
33
33
  # at the next tick.
34
- live_neighbors = sum(neighbor.isAlive for neighbor in self.neighbors)
34
+ live_neighbors = sum(neighbor.is_alive for neighbor in self.neighbors)
35
35
 
36
36
  # Assume nextState is unchanged, unless changed below.
37
- self._nextState = self.state
38
- if self.isAlive:
37
+ self._next_state = self.state
38
+ if self.is_alive:
39
39
  if live_neighbors < 2 or live_neighbors > 3:
40
- self._nextState = self.DEAD
40
+ self._next_state = self.DEAD
41
41
  else:
42
42
  if live_neighbors == 3:
43
- self._nextState = self.ALIVE
43
+ self._next_state = self.ALIVE
44
44
 
45
45
  def assume_state(self):
46
46
  """Set the state to the new computed state -- computed in step()."""
47
- self.state = self._nextState
47
+ self.state = self._next_state
@@ -0,0 +1,51 @@
1
+ from mesa.examples.basic.conways_game_of_life.model import ConwaysGameOfLife
2
+ from mesa.visualization import (
3
+ SolaraViz,
4
+ make_space_component,
5
+ )
6
+
7
+
8
+ def agent_portrayal(agent):
9
+ return {
10
+ "color": "white" if agent.state == 0 else "black",
11
+ "marker": "s",
12
+ "size": 25,
13
+ }
14
+
15
+
16
+ def post_process(ax):
17
+ ax.set_aspect("equal")
18
+ ax.set_xticks([])
19
+ ax.set_yticks([])
20
+
21
+
22
+ model_params = {
23
+ "width": 50,
24
+ "height": 50,
25
+ }
26
+
27
+ # Create initial model instance
28
+ model1 = ConwaysGameOfLife(50, 50)
29
+
30
+ # Create visualization elements. The visualization elements are solara components
31
+ # that receive the model instance as a "prop" and display it in a certain way.
32
+ # Under the hood these are just classes that receive the model instance.
33
+ # You can also author your own visualization elements, which can also be functions
34
+ # that receive the model instance and return a valid solara component.
35
+ SpaceGraph = make_space_component(
36
+ agent_portrayal, post_process=post_process, draw_grid=False
37
+ )
38
+
39
+
40
+ # Create the SolaraViz page. This will automatically create a server and display the
41
+ # visualization elements in a web browser.
42
+ # Display it using the following command in the example directory:
43
+ # solara run app.py
44
+ # It will automatically update and display any changes made to this file
45
+ page = SolaraViz(
46
+ model1,
47
+ components=[SpaceGraph],
48
+ model_params=model_params,
49
+ name="Game of Life",
50
+ )
51
+ page # noqa
@@ -1,15 +1,14 @@
1
1
  from mesa import Model
2
+ from mesa.examples.basic.conways_game_of_life.agents import Cell
2
3
  from mesa.space import SingleGrid
3
4
 
4
- from .agents import Cell
5
-
6
5
 
7
6
  class ConwaysGameOfLife(Model):
8
7
  """Represents the 2-dimensional array of cells in Conway's Game of Life."""
9
8
 
10
- def __init__(self, width=50, height=50):
9
+ def __init__(self, width=50, height=50, seed=None):
11
10
  """Create a new playing area of (width, height) cells."""
12
- super().__init__()
11
+ super().__init__(seed=seed)
13
12
  # Use a simple grid, where edges wrap around.
14
13
  self.grid = SingleGrid(width, height, torus=True)
15
14
 
@@ -4,7 +4,8 @@ import altair as alt
4
4
  import numpy as np
5
5
  import pandas as pd
6
6
  import streamlit as st
7
- from model import ConwaysGameOfLife
7
+
8
+ from mesa.examples.basic.conways_game_of_life.model import ConwaysGameOfLife
8
9
 
9
10
  model = st.title("Conway's Game of Life")
10
11
  num_ticks = st.slider("Select number of Steps", min_value=1, max_value=100, value=50)