Skip to content

Commit 5de3559

Browse files
committed
merge experimental boltzmann wealth into boltzmann wealth example
1 parent bbe0636 commit 5de3559

File tree

15 files changed

+191
-349
lines changed

15 files changed

+191
-349
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ This is based on Dorigo's Ant System "Swarm Intelligence" algorithm for generati
114114

115115
## Visualization Examples
116116

117-
### [Boltzmann Wealth Model (Experimental)](https://github.com/projectmesa/mesa-examples/tree/main/examples/boltzmann_wealth_model_experimental)
117+
### [Boltzmann Wealth Model)](https://github.com/projectmesa/mesa-examples/tree/main/examples/boltzmann_wealth_model)
118118

119-
Boltzmann Wealth model with the experimental Juptyer notebook visualization feature.
119+
Boltzmann Wealth model with an optional visualization using Streamlit.
120120

121121
### [Charts Example](https://github.com/projectmesa/mesa-examples/tree/main/examples/charts)
122122

examples/boltzmann_wealth_model/Readme.md

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,41 @@ As the model runs, the distribution of wealth among agents goes from being perfe
1212

1313
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)
1414

15-
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:
15+
Make sure to install the requirements first:
1616

1717
```
18-
$ python server.py
18+
$ pip install -r requirements.txt
1919
```
2020

21-
Make sure to install the requirements first:
21+
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:
2222

2323
```
24-
pip install -r requirements.txt
24+
$ solara run app.py
2525
```
2626

27-
If your browser doesn't open automatically, point it to [http://127.0.0.1:8521/](http://127.0.0.1:8521/). When the visualization loads, press Reset, then Run.
27+
If your browser doesn't open automatically, point it to [http://127.0.0.1:8765/](http://127.0.0.1:8765/). When the visualization loads, click on the Play button.
2828

2929

3030
## Files
3131

32-
* ``boltzmann_wealth_model/model.py``: Final version of the model.
33-
* ``boltzmann_wealth_model/server.py``: Code for the interactive visualization.
34-
* ``run.py``: Launches the server.
32+
* ``model.py``: Final version of the model.
33+
* ``app.py``: Code for the interactive visualization.
3534

3635
## Optional
3736

38-
* ``boltzmann_wealth_model/app.py``: can be used to run the simulation via the streamlit interface.
39-
* For this some additional packages like ``streamlit`` and ``altair`` needs to be installed.
40-
* Once installed, the app can be opened in the browser using : ``streamlit run app.py``
37+
An optional visualization is also provided using Streamlit, which is another popular Python library for creating interactive web applications.
38+
39+
To run the Streamlit app, you will need to install the `streamlit` and `altair` libraries:
40+
41+
```
42+
$ pip install streamlit altair
43+
```
44+
45+
Then, you can run the Streamlit app using the following command:
46+
47+
```
48+
$ streamlit run st_app.py
49+
```
4150

4251
## Further Reading
4352

Lines changed: 54 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,65 @@
1-
import time
2-
3-
import altair as alt
4-
import pandas as pd
5-
import streamlit as st
6-
from boltzmann_wealth_model.model import BoltzmannWealthModel
7-
8-
model = st.title("Boltzman Wealth Model")
9-
num_agents = st.slider(
10-
"Choose how many agents to include in the model",
11-
min_value=1,
12-
max_value=100,
13-
value=50,
1+
from mesa.visualization import (
2+
SolaraViz,
3+
make_plot_measure,
4+
make_space_matplotlib,
145
)
15-
num_ticks = st.slider(
16-
"Select number of Simulation Runs", min_value=1, max_value=100, value=50
17-
)
18-
height = st.slider("Select Grid Height", min_value=10, max_value=100, step=10, value=15)
19-
width = st.slider("Select Grid Width", min_value=10, max_value=100, step=10, value=20)
20-
model = BoltzmannWealthModel(num_agents, height, width)
21-
6+
from model import BoltzmannWealthModel
227

23-
status_text = st.empty()
24-
run = st.button("Run Simulation")
258

9+
def agent_portrayal(agent):
10+
size = 10
11+
color = "tab:red"
12+
if agent.wealth > 0:
13+
size = 50
14+
color = "tab:blue"
15+
return {"size": size, "color": color}
2616

27-
if run:
28-
tick = time.time()
29-
step = 0
30-
# init grid
31-
df_grid = pd.DataFrame()
32-
df_gini = pd.DataFrame({"step": [0], "gini": [-1]})
33-
for x in range(width):
34-
for y in range(height):
35-
df_grid = pd.concat(
36-
[df_grid, pd.DataFrame({"x": [x], "y": [y], "agent_count": 0})],
37-
ignore_index=True,
38-
)
3917

40-
heatmap = (
41-
alt.Chart(df_grid)
42-
.mark_point(size=100)
43-
.encode(x="x", y="y", color=alt.Color("agent_count"))
44-
.interactive()
45-
.properties(width=800, height=600)
46-
)
18+
model_params = {
19+
"N": {
20+
"type": "SliderInt",
21+
"value": 50,
22+
"label": "Number of agents:",
23+
"min": 10,
24+
"max": 100,
25+
"step": 1,
26+
},
27+
"width": 10,
28+
"height": 10,
29+
}
4730

48-
line = (
49-
alt.Chart(df_gini)
50-
.mark_line(point=True)
51-
.encode(x="step", y="gini")
52-
.properties(width=800, height=600)
53-
)
31+
# Create initial model instance
32+
model1 = BoltzmannWealthModel(50, 10, 10)
5433

55-
# init progress bar
56-
my_bar = st.progress(0, text="Simulation Progress") # progress
57-
placeholder = st.empty()
58-
st.subheader("Agent Grid")
59-
chart = st.altair_chart(heatmap)
60-
st.subheader("Gini Values")
61-
line_chart = st.altair_chart(line)
34+
# Create visualization elements. The visualization elements are solara components
35+
# that receive the model instance as a "prop" and display it in a certain way.
36+
# Under the hood these are just classes that receive the model instance.
37+
# You can also author your own visualization elements, which can also be functions
38+
# that receive the model instance and return a valid solara component.
39+
SpaceGraph = make_space_matplotlib(agent_portrayal)
40+
GiniPlot = make_plot_measure("Gini")
6241

63-
color_scale = alt.Scale(
64-
domain=[0, 1, 2, 3, 4], range=["red", "cyan", "white", "white", "blue"]
65-
)
66-
for i in range(num_ticks):
67-
model.step()
68-
my_bar.progress((i / num_ticks), text="Simulation progress")
69-
placeholder.text("Step = %d" % i)
70-
for cell in model.grid.coord_iter():
71-
cell_content, (x, y) = cell
72-
agent_count = len(cell_content)
73-
selected_row = df_grid[(df_grid["x"] == x) & (df_grid["y"] == y)]
74-
df_grid.loc[selected_row.index, "agent_count"] = (
75-
agent_count # random.choice([1,2])
76-
)
77-
78-
df_gini = pd.concat(
79-
[
80-
df_gini,
81-
pd.DataFrame(
82-
{"step": [i], "gini": [model.datacollector.model_vars["Gini"][i]]}
83-
),
84-
]
85-
)
86-
# st.table(df_grid)
87-
heatmap = (
88-
alt.Chart(df_grid)
89-
.mark_circle(size=100)
90-
.encode(x="x", y="y", color=alt.Color("agent_count", scale=color_scale))
91-
.interactive()
92-
.properties(width=800, height=600)
93-
)
94-
chart.altair_chart(heatmap)
95-
96-
line = (
97-
alt.Chart(df_gini)
98-
.mark_line(point=True)
99-
.encode(x="step", y="gini")
100-
.properties(width=800, height=600)
101-
)
102-
line_chart.altair_chart(line)
42+
# Create the SolaraViz page. This will automatically create a server and display the
43+
# visualization elements in a web browser.
44+
# Display it using the following command in the example directory:
45+
# solara run app.py
46+
# It will automatically update and display any changes made to this file
47+
page = SolaraViz(
48+
model1,
49+
components=[SpaceGraph, GiniPlot],
50+
model_params=model_params,
51+
name="Boltzmann Wealth Model",
52+
)
53+
page # noqa
10354

104-
time.sleep(0.01)
10555

106-
tock = time.time()
107-
st.success(f"Simulation completed in {tock - tick:.2f} secs")
56+
# In a notebook environment, we can also display the visualization elements directly
57+
# SpaceGraph(model1)
58+
# GiniPlot(model1)
10859

109-
# st.subheader('Agent Grid')
110-
# fig = px.imshow(agent_counts,labels={'color':'Agent Count'})
111-
# st.plotly_chart(fig)
112-
# st.subheader('Gini value over sim ticks (Plotly)')
113-
# chart = st.line_chart(model.datacollector.model_vars['Gini'])
60+
# The plots will be static. If you want to pick up model steps,
61+
# you have to make the model reactive first
62+
# reactive_model = solara.reactive(model1)
63+
# SpaceGraph(reactive_model)
64+
# In a different notebook block:
65+
# reactive_model.value.step()

examples/boltzmann_wealth_model/boltzmann_wealth_model/__init__.py

Whitespace-only changes.

examples/boltzmann_wealth_model/boltzmann_wealth_model/server.py

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
mesa~=2.0
1+
mesa[viz]>=3.0.0b0

examples/boltzmann_wealth_model/run.py

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import time
2+
3+
import altair as alt
4+
import pandas as pd
5+
import streamlit as st
6+
from model import BoltzmannWealthModel
7+
8+
model = st.title("Boltzman Wealth Model")
9+
num_agents = st.slider(
10+
"Choose how many agents to include in the model",
11+
min_value=1,
12+
max_value=100,
13+
value=50,
14+
)
15+
num_ticks = st.slider(
16+
"Select number of Simulation Runs", min_value=1, max_value=100, value=50
17+
)
18+
height = st.slider("Select Grid Height", min_value=10, max_value=100, step=10, value=15)
19+
width = st.slider("Select Grid Width", min_value=10, max_value=100, step=10, value=20)
20+
model = BoltzmannWealthModel(num_agents, height, width)
21+
22+
23+
status_text = st.empty()
24+
run = st.button("Run Simulation")
25+
26+
27+
if run:
28+
tick = time.time()
29+
step = 0
30+
# init grid
31+
df_grid = pd.DataFrame()
32+
df_gini = pd.DataFrame({"step": [0], "gini": [-1]})
33+
for x in range(width):
34+
for y in range(height):
35+
df_grid = pd.concat(
36+
[df_grid, pd.DataFrame({"x": [x], "y": [y], "agent_count": 0})],
37+
ignore_index=True,
38+
)
39+
40+
heatmap = (
41+
alt.Chart(df_grid)
42+
.mark_point(size=100)
43+
.encode(x="x", y="y", color=alt.Color("agent_count"))
44+
.interactive()
45+
.properties(width=800, height=600)
46+
)
47+
48+
line = (
49+
alt.Chart(df_gini)
50+
.mark_line(point=True)
51+
.encode(x="step", y="gini")
52+
.properties(width=800, height=600)
53+
)
54+
55+
# init progress bar
56+
my_bar = st.progress(0, text="Simulation Progress") # progress
57+
placeholder = st.empty()
58+
st.subheader("Agent Grid")
59+
chart = st.altair_chart(heatmap)
60+
st.subheader("Gini Values")
61+
line_chart = st.altair_chart(line)
62+
63+
color_scale = alt.Scale(
64+
domain=[0, 1, 2, 3, 4], range=["red", "cyan", "white", "white", "blue"]
65+
)
66+
for i in range(num_ticks):
67+
model.step()
68+
my_bar.progress((i / num_ticks), text="Simulation progress")
69+
placeholder.text("Step = %d" % i)
70+
for cell in model.grid.coord_iter():
71+
cell_content, (x, y) = cell
72+
agent_count = len(cell_content)
73+
selected_row = df_grid[(df_grid["x"] == x) & (df_grid["y"] == y)]
74+
df_grid.loc[selected_row.index, "agent_count"] = (
75+
agent_count # random.choice([1,2])
76+
)
77+
78+
df_gini = pd.concat(
79+
[
80+
df_gini,
81+
pd.DataFrame(
82+
{"step": [i], "gini": [model.datacollector.model_vars["Gini"][i]]}
83+
),
84+
]
85+
)
86+
# st.table(df_grid)
87+
heatmap = (
88+
alt.Chart(df_grid)
89+
.mark_circle(size=100)
90+
.encode(x="x", y="y", color=alt.Color("agent_count", scale=color_scale))
91+
.interactive()
92+
.properties(width=800, height=600)
93+
)
94+
chart.altair_chart(heatmap)
95+
96+
line = (
97+
alt.Chart(df_gini)
98+
.mark_line(point=True)
99+
.encode(x="step", y="gini")
100+
.properties(width=800, height=600)
101+
)
102+
line_chart.altair_chart(line)
103+
104+
time.sleep(0.01)
105+
106+
tock = time.time()
107+
st.success(f"Simulation completed in {tock - tick:.2f} secs")
108+
109+
# st.subheader('Agent Grid')
110+
# fig = px.imshow(agent_counts,labels={'color':'Agent Count'})
111+
# st.plotly_chart(fig)
112+
# st.subheader('Gini value over sim ticks (Plotly)')
113+
# chart = st.line_chart(model.datacollector.model_vars['Gini'])

0 commit comments

Comments
 (0)