Skip to content

Commit 3e2de47

Browse files
Update Conway example (#2403)
* add solara app * Update Readme.md * cleanup * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 91b8047 commit 3e2de47

File tree

4 files changed

+121
-96
lines changed

4 files changed

+121
-96
lines changed

mesa/examples/basic/conways_game_of_life/Readme.md

+11-7
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,30 @@ The "game" is a zero-player game, meaning that its evolution is determined by it
99

1010
## How to Run
1111

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
1313

1414
```
15-
$ mesa runserver
15+
$ solara run app.py
1616
```
1717

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.
1925

2026
## Files
2127

2228
* ``agents.py``: Defines the behavior of an individual cell, which can be in two states: DEAD or ALIVE.
2329
* ``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.
2531
* ``st_app.py``: Defines an interactive visualization using Streamlit.
2632

2733
## Optional
2834

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)
3236

3337

3438
## Further Reading
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,39 @@
1-
import time
2-
3-
import altair as alt
4-
import numpy as np
5-
import pandas as pd
6-
import streamlit as st
7-
81
from mesa.examples.basic.conways_game_of_life.model import ConwaysGameOfLife
9-
10-
model = st.title("Conway's Game of Life")
11-
num_ticks = st.slider("Select number of Steps", min_value=1, max_value=100, value=50)
12-
height = st.slider("Select Grid Height", min_value=10, max_value=100, step=10, value=15)
13-
width = st.slider("Select Grid Width", min_value=10, max_value=100, step=10, value=20)
14-
model = ConwaysGameOfLife(height, width)
15-
16-
col1, col2, col3 = st.columns(3)
17-
status_text = st.empty()
18-
# step_mode = st.checkbox('Run Step-by-Step')
19-
run = st.button("Run Simulation")
20-
21-
22-
if run:
23-
tick = time.time()
24-
step = 0
25-
# init grid
26-
df_grid = pd.DataFrame()
27-
agent_counts = np.zeros((model.grid.width, model.grid.height))
28-
for x in range(width):
29-
for y in range(height):
30-
df_grid = pd.concat(
31-
[df_grid, pd.DataFrame({"x": [x], "y": [y], "state": [0]})],
32-
ignore_index=True,
33-
)
34-
35-
heatmap = (
36-
alt.Chart(df_grid)
37-
.mark_point(size=100)
38-
.encode(x="x", y="y", color=alt.Color("state"))
39-
.interactive()
40-
.properties(width=800, height=600)
41-
)
42-
43-
# init progress bar
44-
my_bar = st.progress(0, text="Simulation Progress") # progress
45-
placeholder = st.empty()
46-
st.subheader("Agent Grid")
47-
chart = st.altair_chart(heatmap, use_container_width=True)
48-
color_scale = alt.Scale(domain=[0, 1], range=["red", "yellow"])
49-
for i in range(num_ticks):
50-
model.step()
51-
my_bar.progress((i / num_ticks), text="Simulation progress")
52-
placeholder.text("Step = %d" % i)
53-
for contents, (x, y) in model.grid.coord_iter():
54-
# print('x:',x,'y:',y, 'state:',contents)
55-
selected_row = df_grid[(df_grid["x"] == x) & (df_grid["y"] == y)]
56-
df_grid.loc[selected_row.index, "state"] = (
57-
contents.state
58-
) # random.choice([1,2])
59-
60-
heatmap = (
61-
alt.Chart(df_grid)
62-
.mark_circle(size=100)
63-
.encode(x="x", y="y", color=alt.Color("state", scale=color_scale))
64-
.interactive()
65-
.properties(width=800, height=600)
66-
)
67-
chart.altair_chart(heatmap)
68-
69-
time.sleep(0.1)
70-
71-
tock = time.time()
72-
st.success(f"Simulation completed in {tock - tick:.2f} secs")
2+
from mesa.visualization import (
3+
SolaraViz,
4+
make_space_matplotlib,
5+
)
6+
7+
8+
def agent_portrayal(agent):
9+
return {"color": "white" if agent.state == 0 else "black"}
10+
11+
12+
model_params = {
13+
"width": 50,
14+
"height": 50,
15+
}
16+
17+
# Create initial model instance
18+
model1 = ConwaysGameOfLife(50, 50)
19+
20+
# Create visualization elements. The visualization elements are solara components
21+
# that receive the model instance as a "prop" and display it in a certain way.
22+
# Under the hood these are just classes that receive the model instance.
23+
# You can also author your own visualization elements, which can also be functions
24+
# that receive the model instance and return a valid solara component.
25+
SpaceGraph = make_space_matplotlib(agent_portrayal)
26+
27+
28+
# Create the SolaraViz page. This will automatically create a server and display the
29+
# visualization elements in a web browser.
30+
# Display it using the following command in the example directory:
31+
# solara run app.py
32+
# It will automatically update and display any changes made to this file
33+
page = SolaraViz(
34+
model1,
35+
components=[SpaceGraph],
36+
model_params=model_params,
37+
name="Game of Life",
38+
)
39+
page # noqa

mesa/examples/basic/conways_game_of_life/portrayal.py

-18
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import time
2+
3+
import altair as alt
4+
import numpy as np
5+
import pandas as pd
6+
import streamlit as st
7+
8+
from mesa.examples.basic.conways_game_of_life.model import ConwaysGameOfLife
9+
10+
model = st.title("Conway's Game of Life")
11+
num_ticks = st.slider("Select number of Steps", min_value=1, max_value=100, value=50)
12+
height = st.slider("Select Grid Height", min_value=10, max_value=100, step=10, value=15)
13+
width = st.slider("Select Grid Width", min_value=10, max_value=100, step=10, value=20)
14+
model = ConwaysGameOfLife(height, width)
15+
16+
col1, col2, col3 = st.columns(3)
17+
status_text = st.empty()
18+
# step_mode = st.checkbox('Run Step-by-Step')
19+
run = st.button("Run Simulation")
20+
21+
22+
if run:
23+
tick = time.time()
24+
step = 0
25+
# init grid
26+
df_grid = pd.DataFrame()
27+
agent_counts = np.zeros((model.grid.width, model.grid.height))
28+
for x in range(width):
29+
for y in range(height):
30+
df_grid = pd.concat(
31+
[df_grid, pd.DataFrame({"x": [x], "y": [y], "state": [0]})],
32+
ignore_index=True,
33+
)
34+
35+
heatmap = (
36+
alt.Chart(df_grid)
37+
.mark_point(size=100)
38+
.encode(x="x", y="y", color=alt.Color("state"))
39+
.interactive()
40+
.properties(width=800, height=600)
41+
)
42+
43+
# init progress bar
44+
my_bar = st.progress(0, text="Simulation Progress") # progress
45+
placeholder = st.empty()
46+
st.subheader("Agent Grid")
47+
chart = st.altair_chart(heatmap, use_container_width=True)
48+
color_scale = alt.Scale(domain=[0, 1], range=["red", "yellow"])
49+
for i in range(num_ticks):
50+
model.step()
51+
my_bar.progress((i / num_ticks), text="Simulation progress")
52+
placeholder.text("Step = %d" % i)
53+
for contents, (x, y) in model.grid.coord_iter():
54+
# print('x:',x,'y:',y, 'state:',contents)
55+
selected_row = df_grid[(df_grid["x"] == x) & (df_grid["y"] == y)]
56+
df_grid.loc[selected_row.index, "state"] = (
57+
contents.state
58+
) # random.choice([1,2])
59+
60+
heatmap = (
61+
alt.Chart(df_grid)
62+
.mark_circle(size=100)
63+
.encode(x="x", y="y", color=alt.Color("state", scale=color_scale))
64+
.interactive()
65+
.properties(width=800, height=600)
66+
)
67+
chart.altair_chart(heatmap)
68+
69+
time.sleep(0.1)
70+
71+
tock = time.time()
72+
st.success(f"Simulation completed in {tock - tick:.2f} secs")

0 commit comments

Comments
 (0)