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.