Note
You can download this demonstration as a Jupyter Notebook
here
Wealth transfer¶
This is a tutorial for beginners on how to create a simple agent-based model with the agentpy package. It shows the how to create a basic model with a custom agent type, run a simulation, record data, and visualize results.
About the model¶
The model explores the distribution of wealth under a trading population of agents. We will see that their random interaction will create an inequality of wealth that follows a Boltzmann distribution. The original version of this model been written in MESA and can be found here.
Getting started¶
To install the latest version of agentpy, run the following command:
[1]:
# !pip install agentpy
Once installed, the recommended way to import the package is as follows:
[2]:
import agentpy as ap
We also import two other libraries that will be used in this demonstration.
[3]:
import numpy as np # Scientific computing tools
import matplotlib.pyplot as plt # Visualization
Model definition¶
We start by defining a new type of agent as a subcluss of Agent
.
Each agent starts with one unit of wealth
.
When wealth_transfer()
is called, the agent selects another agent at random
and gives them one unit of their own wealth if they have one to spare.
[4]:
class WealthAgent(ap.Agent):
""" An agent with wealth """
def setup(self):
self.wealth = 1
def wealth_transfer(self):
if self.wealth > 0:
partner = self.model.agents.random()
partner.wealth += 1
self.wealth -= 1
Next, we define a method to calculate the Gini Coefficient, which will measure the inequality among our agents.
[5]:
def gini(x):
""" Calculate Gini Coefficient """
# By Warren Weckesser https://stackoverflow.com/a/39513799
mad = np.abs(np.subtract.outer(x, x)).mean() # Mean absolute difference
rmad = mad / np.mean(x) # Relative mean absolute difference
return 0.5 * rmad
Finally, we define our model as a subclass of Model
. In Model.setup()
, we define how many agents should be created at the beginning of the simulation. In Model.step()
, we define that at every time-step all agents will perform the action wealth_transfer. In Model.update()
, we calculate and record the current Gini coefficient. And in Model.end()
, we further record the wealth of each agent.
[6]:
class WealthModel(ap.Model):
""" A simple model of random wealth transfers """
def setup(self):
self.add_agents(self.p.agents, WealthAgent)
def step(self):
self.agents.wealth_transfer()
def update(self):
self.record('Gini Coefficient', gini(self.agents.wealth))
def end(self):
self.agents.record('wealth')
Running a simulation¶
To run a simulation, we define a dictionary of parameters that defines the number of agents and the number of steps that the model will run.
[7]:
parameters = {
'agents': 100,
'steps': 100
}
To perform a simulation, we initialize our model with these parameters and call the method Model.run
, which returns a DataDict
of our recorded variables and measures.
[8]:
model = WealthModel(parameters)
results = model.run()
Completed: 100 steps
Run time: 0:00:00.183086
Simulation finished
To visualize the evolution of our Gini Coefficient,
we can use pandas.DataFrame.plot()
.
[9]:
data = results.variables.WealthModel
ax = data.plot()

And to visualize the final distribution of wealth,
we can use pandas.DataFrame.hist()
.
[10]:
data = results.variables.WealthAgent
data.hist(bins=range(data.wealth.max()+1))
plt.title('')
plt.xlabel('Wealth')
plt.ylabel('Number of agents')
plt.show()

What we get is a Boltzmann distribution. For those interested to understand this result, you can read more about it here.