diff --git a/.virtual_documents/docs/tutorials/intro_tutorial.ipynb b/.virtual_documents/docs/tutorials/intro_tutorial.ipynb deleted file mode 100644 index 041361abd4e..00000000000 --- a/.virtual_documents/docs/tutorials/intro_tutorial.ipynb +++ /dev/null @@ -1,928 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - -import mesa - -# Data visualization tools. -import seaborn as sns - -# Has multi-dimensional arrays and matrices. Has a large collection of -# mathematical functions to operate on these arrays. -import numpy as np - -# Data manipulation and analysis. -import pandas as pd - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - # Pass the parameters to the parent class. - super().__init__(model) - - # Create the agent's variable and set the initial values. - self.wealth = 1 - - - - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, seed=None): - super().__init__(seed=seed) - self.num_agents = n - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - # Pass the parameters to the parent class. - super().__init__(model) - - # Create the agent's attribute and set the initial values. - self.wealth = 1 - - def say_hi(self): - # The agent's step will go here. - # For demonstration purposes we will print the agent's unique_id - print(f"Hi, I am an agent, you can call me {str(self.unique_id)}.") - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, seed=None): - super().__init__(seed=seed) - self.num_agents = n - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) # This calls the agent class parameter n number of times - - def step(self): - """Advance the model by one step.""" - - # This function psuedo-randomly reorders the list of agent objects and - # then iterates through calling the function passed in as the parameter - self.agents.shuffle_do("say_hi") - - - - - -starter_model = MoneyModel(10) -starter_model.step() - - -# Run this step a few times and see what happens! notice the order of the agents changes each time. -starter_model.step() - - -# Challenge: Change the seed from None to a number like 42 and see the impact - - -# Challenge: Change `shuffle_do` to just `do` and see the impact - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - # Pass the parameters to the parent class. - super().__init__(model) - - # Create the agent's variable and set the initial values. - self.wealth = 1 - - def say_wealth(self): - # The agent's step will go here. - # FIXME: need to print the agent's wealth - print(f"Hi, I am an agent and I am broke!") - - - - - -# Fixme: Create the model object, and run it - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - # Pass the parameters to the parent class. - super().__init__(model) - - # Create the agent's variable and set the initial values. - self.wealth = 1 - - def exchange(self): - # Verify agent has some wealth - if self.wealth > 0: - other_agent = self.random.choice(self.model.agents) - if other_agent is not None: - other_agent.wealth += 1 - self.wealth -= 1 - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n): - super().__init__() - self.num_agents = n - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) # This calls the agent class parameter n number of times - - def step(self): - """Advance the model by one step.""" - - # This function psuedo-randomly reorders the list of agent objects and - # then iterates through calling the function passed in as the parameter - self.agents.shuffle_do("exchange") - - - - - -model = MoneyModel(10) # Tels the model to create 10 agents -for _ in range(30): #Runs the model for 10 steps; an underscore is common convention for a variable that is not used - model.step() - - - - - -agent_wealth = [a.wealth for a in model.agents] -# Create a histogram with seaborn -g = sns.histplot(agent_wealth, discrete=True) -g.set( - title="Wealth distribution", xlabel="Wealth", ylabel="number of agents" -); # The semicolon is just to avoid printing the object representation - - - - - -all_wealth = [] -# This runs the model 100 times, each model executing 10 steps. -for _ in range(100): - # Run the model - model = MoneyModel(10) - for _ in range(30): - model.step() - - # Store the results - for agent in model.agents: - all_wealth.append(agent.wealth) - -# Use seaborn -g = sns.histplot(all_wealth, discrete=True) -g.set(title="Wealth distribution", xlabel="Wealth", ylabel="number of agents"); - - - - - - - - - - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, width, height, seed=None): - super().__init__(seed=seed) - self.num_agents = n - self.grid = mesa.space.MultiGrid(width, height, True) - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - - # Add the agent to a random grid cell - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(a, (x, y)) - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - super().__init__(model) - self.wealth = 1 - - def move(self): - possible_steps = self.model.grid.get_neighborhood( - self.pos, moore=True, include_center=False - ) - new_position = self.random.choice(possible_steps) - self.model.grid.move_agent(self, new_position) - - def give_money(self): - cellmates = self.model.grid.get_cell_list_contents([self.pos]) - if len(cellmates) > 1: - other_agent = self.random.choice(cellmates) - other_agent.wealth += 1 - self.wealth -= 1 - - def step(self): - self.move() - if self.wealth > 0: - self.give_money() - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, width, height,seed=None): - super().__init__(seed=seed) - self.num_agents = n - self.grid = mesa.space.MultiGrid(width, height, True) - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - # Add the agent to a random grid cell - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(a, (x, y)) - - def step(self): - self.agents.shuffle_do("step") - - - - - -model = MoneyModel(100, 10, 10) -for _ in range(20): - model.step() - - - - - -agent_counts = np.zeros((model.grid.width, model.grid.height)) -for cell_content, (x, y) in model.grid.coord_iter(): - agent_count = len(cell_content) - agent_counts[x][y] = agent_count -# Plot using seaborn, with a visual size of 5x5 -g = sns.heatmap(agent_counts, cmap="viridis", annot=True, cbar=False, square=True) -g.figure.set_size_inches(5, 5) -g.set(title="number of agents on each cell of the grid"); - - -# Challenge: Change the size of the grid - - -# Challenge: Change from multigrid to grid (only one agent per cell) - - - - - -def compute_gini(model): - agent_wealths = [agent.wealth for agent in model.agents] - x = sorted(agent_wealths) - n = model.num_agents - B = sum(xi * (n - i) for i, xi in enumerate(x)) / (n * sum(x)) - return 1 + (1 / n) - 2 * B - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - super().__init__(model) - self.wealth = 1 - - def move(self): - possible_steps = self.model.grid.get_neighborhood( - self.pos, moore=True, include_center=False - ) - new_position = self.random.choice(possible_steps) - self.model.grid.move_agent(self, new_position) - - def give_money(self): - cellmates = self.model.grid.get_cell_list_contents([self.pos]) - cellmates.pop( - cellmates.index(self) - ) # Ensure agent is not giving money to itself - if len(cellmates) > 1: - other = self.random.choice(cellmates) - other.wealth += 1 - self.wealth -= 1 - if other == self: - print("I JUST GAVE MOnEY TO MYSELF HEHEHE!") - - def step(self): - self.move() - if self.wealth > 0: - self.give_money() - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, width, height): - super().__init__() - self.num_agents = n - self.grid = mesa.space.MultiGrid(width, height, True) - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - # Add the agent to a random grid cell - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(a, (x, y)) - - self.datacollector = mesa.DataCollector( - model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"} - ) - - def step(self): - self.datacollector.collect(self) - self.agents.shuffle_do("step") - - - - - -model = MoneyModel(100, 10, 10) -for _ in range(100): - model.step() - - - - - - - - -gini = model.datacollector.get_model_vars_dataframe() -# Plot the Gini coefficient over time -g = sns.lineplot(data=gini) -g.set(title="Gini Coefficient over Time", ylabel="Gini Coefficient"); - - - - - - - - -agent_wealth = model.datacollector.get_agent_vars_dataframe() -agent_wealth.head() - - - - - -last_step = agent_wealth.index.get_level_values("Step").max() -end_wealth = agent_wealth.xs(last_step, level="Step")["Wealth"] -# Create a histogram of wealth at the last step -g = sns.histplot(end_wealth, discrete=True) -g.set( - title="Distribution of wealth at the end of simulation", - xlabel="Wealth", - ylabel="number of agents", -); - - - - - -# Get the wealth of agent 14 over time -one_agent_wealth = agent_wealth.xs(7, level="AgentID") - -# Plot the wealth of agent 7 over time -g = sns.lineplot(data=one_agent_wealth, x="Step", y="Wealth") -g.set(title="Wealth of agent 7 over time"); - - - - - -agent_list = [3, 14, 25] - -# Get the wealth of multiple agents over time -multiple_agents_wealth = agent_wealth[ - agent_wealth.index.get_level_values("AgentID").isin(agent_list) -] -# Plot the wealth of multiple agents over time -g = sns.lineplot(data=multiple_agents_wealth, x="Step", y="Wealth", hue="AgentID") -g.set(title="Wealth of agents 3, 14 and 25 over time"); - - - - - -# Transform the data to a long format -agent_wealth_long = agent_wealth.T.unstack().reset_index() -agent_wealth_long.columns = ["Step", "AgentID", "Variable", "Value"] -agent_wealth_long.head(3) - -# Plot the average wealth over time -g = sns.lineplot(data=agent_wealth_long, x="Step", y="Value", errorbar=("ci", 95)) -g.set(title="Average wealth over time") - - - - - - - - -# save the model data (stored in the pandas gini object) to CSV -gini.to_csv("model_data.csv") - -# save the agent data (stored in the pandas agent_wealth object) to CSV -agent_wealth.to_csv("agent_data.csv") - - - - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - super().__init__(model) - self.wealth = 1 - - def move(self): - possible_steps = self.model.grid.get_neighborhood( - self.pos, moore=True, include_center=False - ) - new_position = self.random.choice(possible_steps) - self.model.grid.move_agent(self, new_position) - - def give_money(self): - if self.wealth > 0: - cellmates = self.model.grid.get_cell_list_contents([self.pos]) - if len(cellmates) > 1: - other_agent = self.random.choice(cellmates) - other_agent.wealth += 1 - self.wealth -= 1 - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, width, height,seed=None): - super().__init__(seed=seed) - self.num_agents = n - self.grid = mesa.space.MultiGrid(width, height, True) - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - # Add the agent to a random grid cell - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(a, (x, y)) - - self.datacollector = mesa.DataCollector( - model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"} - ) - - def step(self): - self.datacollector.collect(self) - self.agents.shuffle_do("move") - self.agents.do("give_money") - - - - - -model = MoneyModel(100, 10, 10) -for _ in range(20): - model.step() - - - - - -agent_counts = np.zeros((model.grid.width, model.grid.height)) -for cell_content, (x, y) in model.grid.coord_iter(): - agent_count = len(cell_content) - agent_counts[x][y] = agent_count -# Plot using seaborn, with a visual size of 5x5 -g = sns.heatmap(agent_counts, cmap="viridis", annot=True, cbar=False, square=True) -g.figure.set_size_inches(5, 5) -g.set(title="Number of agents on each cell of the grid"); - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - super().__init__(model) - self.wealth = 1 - - def give_money(self, poor_agents): - if self.wealth > 0: - other_agent = self.random.choice(poor_agents) - other_agent.wealth += 1 - self.wealth -= 1 - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n): - super().__init__() - self.num_agents = n - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - - self.datacollector = mesa.DataCollector( - model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"} - ) - - def step(self): - self.datacollector.collect(self) - # Get lists of rich and poor agents - rich_agents = model.agents.select(lambda a: a.wealth >= 3) - poor_agents = model.agents.select(lambda a: a.wealth < 3) - # When there is rich agents only have them give money to the poor agents - if len(rich_agents) > 0: - rich_agents.shuffle_do("give_money", poor_agents) - else: - poor_agents.shuffle_do("give_money", poor_agents) - - - - - -model = MoneyModel(100) -for _ in range(20): - model.step() - - -data = model.datacollector.get_agent_vars_dataframe() -# Use seaborn -g = sns.histplot(data["Wealth"], discrete=True) -g.set(title="Wealth distribution", xlabel="Wealth", ylabel="number of agents"); - - - - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model, ethnicity): - super().__init__(model) - self.wealth = 1 - self.ethnicity = ethnicity - - def give_money(self, similars): - if self.wealth > 0: - other_agent = self.random.choice(similars) - other_agent.wealth += 1 - self.wealth -= 1 - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n): - super().__init__() - self.num_agents = n - - # Create a list of our different ethnicities - ethnicities = ["Green", "Blue", "Mixed"] - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self, self.random.choice(ethnicities)) - - self.datacollector = mesa.DataCollector( - model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth", "Ethnicity":"ethnicity"} - ) - - def step(self): - self.datacollector.collect(self) - # groupby returns a dictionary of the different ethnicities with a list of agents - grouped_agents = grouped_agents = model.agents.groupby("ethnicity") - - for ethnic, similars in grouped_agents: - if ethnic != "Mixed": - similars.shuffle_do("give_money", similars) - else: - similars.shuffle_do("give_money", self.agents) # This allows mixed to trade with anyone - - - - -# Run the model -model = MoneyModel(100) -for _ in range(20): - model.step() - -# get the data -data = model.datacollector.get_agent_vars_dataframe() -# assign histogram colors -palette = {'Green': 'green', 'Blue': 'blue', 'Mixed': 'purple'} -sns.histplot(data=data, x='Wealth', hue='Ethnicity',discrete=True, palette=palette) -g.set(title="Wealth distribution", xlabel="Wealth", ylabel="number of agents"); - - - - - - - - -def compute_gini(model): - agent_wealths = [agent.wealth for agent in model.agents] - x = sorted(agent_wealths) - n = model.num_agents - B = sum(xi * (n - i) for i, xi in enumerate(x)) / (n * sum(x)) - return 1 + (1 / n) - 2 * B - - -class MoneyModel(mesa.Model): - """A model with some number of agents.""" - - def __init__(self, n, width, height, seed=None): - super().__init__(seed=seed) - self.num_agents = n - self.grid = mesa.space.MultiGrid(width, height, True) - self.running = True - - # Create agents - for _ in range(self.num_agents): - a = MoneyAgent(self) - # Add the agent to a random grid cell - x = self.random.randrange(self.grid.width) - y = self.random.randrange(self.grid.height) - self.grid.place_agent(a, (x, y)) - - self.datacollector = mesa.DataCollector( - model_reporters={"Gini": compute_gini}, - agent_reporters={"Wealth": "wealth", "Steps_not_given": "steps_not_given"}, - ) - - def step(self): - self.datacollector.collect(self) - self.agents.shuffle_do("move") - self.agents.shuffle_do("give_money") - - -class MoneyAgent(mesa.Agent): - """An agent with fixed initial wealth.""" - - def __init__(self, model): - super().__init__(model) - self.wealth = 1 - self.steps_not_given = 0 - - def move(self): - possible_steps = self.model.grid.get_neighborhood( - self.pos, moore=True, include_center=False - ) - new_position = self.random.choice(possible_steps) - self.model.grid.move_agent(self, new_position) - - def give_money(self): - cellmates = self.model.grid.get_cell_list_contents([self.pos]) - if len(cellmates) > 1: - other = self.random.choice(cellmates) - other.wealth += 1 - self.wealth -= 1 - self.steps_not_given = 0 - else: - self.steps_not_given += 1 - - - - - - - - - - - -params = {"width": 10, "height": 10, "n": range(5, 100, 5)} - -results = mesa.batch_run( - MoneyModel, - parameters=params, - iterations=7, - max_steps=100, - number_processes=1, - data_collection_period=1, - display_progress=True, -) - - - - - - - - -results_df = pd.DataFrame(results) -print(results_df.keys()) - - - - - -# Filter the results to only contain the data of one agent (the Gini coefficient will be the same for the entire population at any time) at the 100th step of each episode -results_filtered = results_df[(results_df.AgentID == 1) & (results_df.Step == 100)] -results_filtered[["iteration", "n", "Gini"]].reset_index( - drop=True -).head() # Create a scatter plot -g = sns.scatterplot(data=results_filtered, x="n", y="Gini") -g.set( - xlabel="number of agents", - ylabel="Gini coefficient", - title="Gini coefficient vs. number of agents", -); - - - - - -# Create a point plot with error bars -g = sns.pointplot(data=results_filtered, x="n", y="Gini", linestyle='None') -g.figure.set_size_inches(8, 4) -g.set( - xlabel="number of agents", - ylabel="Gini coefficient", - title="Gini coefficient vs. number of agents", -); - - - - - -# First, we filter the results -one_episode_wealth = results_df[(results_df.n == 10) & (results_df.iteration == 2)] -# Then, print the columns of interest of the filtered data frame -print( - one_episode_wealth.to_string( - index=False, columns=["Step", "AgentID", "Wealth"], max_rows=10 - ) -) -# For a prettier display we can also convert the data frame to html, uncomment to test in a Jupyter notebook -# from IPython.display import display, HTML -# display(HTML(one_episode_wealth.to_html(index=False, columns=['Step', 'AgentID', 'Wealth'], max_rows=25))) - - - - - -results_one_episode = results_df[ - (results_df.n == 10) & (results_df.iteration == 1) & (results_df.AgentID == 1) -] -print(results_one_episode.to_string(index=False, columns=["Step", "Gini"], max_rows=10)) - - - - - -params = {"seed":None,"width": 10, "height": 10, "n": [5, 10, 20, 40, 80]} - -results_5s = mesa.batch_run( - MoneyModel, - parameters=params, - iterations=100, - max_steps=120, - number_processes=1, - data_collection_period=1, # Important, otherwise the datacollector will only collect data of the last time step - display_progress=True, -) - -results_5s_df = pd.DataFrame(results_5s) - - -# Again filter the results to only contain the data of one agent (the Gini coefficient will be the same for the entire population at any time) -results_5s_df_filtered = results_5s_df[(results_5s_df.AgentID == 1)] -results_5s_df_filtered.head(3) - - -# Create a lineplot with error bars -g = sns.lineplot( - data=results_5s_df, - x="Step", - y="Gini", - hue="n", - errorbar=("ci", 95), - palette="tab10", -) -g.figure.set_size_inches(8, 4) -plot_title = "Gini coefficient for different population sizes\n(mean over 100 runs, with 95% confidence interval)" -g.set(title=plot_title, ylabel="Gini coefficient"); - - - - - -# Challenge: Treat the seed as a parameter and see the impact on the Gini Coefficient. -# You can also plot the seeds against the Gini Coefficient by changing the "hue" parameter in sns.lineplot function. - - - - - -# Calculate the mean of the wealth and the number of consecutive rounds for all agents in each episode -agg_results_df = ( - results_5s_df.groupby(["iteration", "n", "Step"]) - .agg({"Wealth": "mean", "Steps_not_given": "mean"}) - .reset_index() -) -agg_results_df.head(3) - - -# Create a line plot with error bars -g = sns.lineplot( - data=agg_results_df, x="Step", y="Steps_not_given", hue="n", palette="tab10" -) -g.figure.set_size_inches(8, 4) -g.set( - title="Average number of consecutive rounds without a transaction for different population sizes\n(mean with 95% confidence interval)", - ylabel="Consecutive rounds without a transaction", -); - - - - - - - - -# Challenge update the model, conduct a batch run with a parameter sweep, and visualize your results - - - - - - - - - diff --git a/.virtual_documents/docs/tutorials/visualization_tutorial.ipynb b/.virtual_documents/docs/tutorials/visualization_tutorial.ipynb deleted file mode 100644 index 32349157a43..00000000000 --- a/.virtual_documents/docs/tutorials/visualization_tutorial.ipynb +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - - - - - - - - - -import mesa -print(f"Mesa version: {mesa.__version__}") - -from mesa.visualization import SolaraViz, make_plot_measure, make_space_matplotlib -# Import the local MoneyModel.py -from MoneyModel import MoneyModel - - - -def agent_portrayal(agent): - return { - "color": "tab:blue", - "size": 50, - } - - - - - -model_params = { - "n": { - "type": "SliderInt", - "value": 50, - "label": "Number of agents:", - "min": 10, - "max": 100, - "step": 1, - }, - "width": 10, - "height": 10, -} - - - - - -# Create initial model instance -model1 = MoneyModel(50, 10, 10) - -SpaceGraph = make_space_matplotlib(agent_portrayal) -GiniPlot = make_plot_measure("Gini") - -page = SolaraViz( - model1, - components=[SpaceGraph, GiniPlot], - model_params=model_params, - name="Boltzmann Wealth Model", -) -# This is required to render the visualization in the Jupyter notebook -page - - - - - -import mesa -print(f"Mesa version: {mesa.__version__}") - -from mesa.visualization import SolaraViz, make_plot_measure, make_space_matplotlib -# Import the local MoneyModel.py -from MoneyModel import MoneyModel - - - -def agent_portrayal(agent): - size = 10 - color = "tab:red" - if agent.wealth > 0: - size = 50 - color = "tab:blue" - return {"size": size, "color": color} - -model_params = { - "n": { - "type": "SliderInt", - "value": 50, - "label": "Number of agents:", - "min": 10, - "max": 100, - "step": 1, - }, - "width": 10, - "height": 10, -} - - -# Create initial model instance -model1 = MoneyModel(50, 10, 10) - -SpaceGraph = make_space_matplotlib(agent_portrayal) -GiniPlot = make_plot_measure("Gini") - -page = SolaraViz( - model1, - components=[SpaceGraph, GiniPlot], - model_params=model_params, - name="Boltzmann Wealth Model", -) -# This is required to render the visualization in the Jupyter notebook -page - - - - - -import mesa -print(f"Mesa version: {mesa.__version__}") - -from mesa.visualization import SolaraViz, make_plot_measure, make_space_matplotlib -# Import the local MoneyModel.py -from MoneyModel import MoneyModel - - - -def agent_portrayal(agent): - size = 10 - color = "tab:red" - if agent.wealth > 0: - size = 50 - color = "tab:blue" - return {"size": size, "color": color} - -model_params = { - "n": { - "type": "SliderInt", - "value": 50, - "label": "Number of agents:", - "min": 10, - "max": 100, - "step": 1, - }, - "width": 10, - "height": 10, -} - - -from mesa.visualization import SolaraViz, make_plot_measure, make_space_matplotlib - -# Create initial model instance -model1 = MoneyModel(50, 10, 10) - -SpaceGraph = make_space_matplotlib(agent_portrayal) -GiniPlot = make_plot_measure("Gini") - - -import solara -from matplotlib.figure import Figure -from mesa.visualization.utils import update_counter - -@solara.component -def Histogram(model): - update_counter.get() # This is required to update the counter - # Note: you must initialize a figure using this method instead of - # plt.figure(), for thread safety purpose - fig = Figure() - ax = fig.subplots() - wealth_vals = [agent.wealth for agent in model.agents] - # Note: you have to use Matplotlib's OOP API instead of plt.hist - # because plt.hist is not thread-safe. - ax.hist(wealth_vals, bins=10) - solara.FigureMatplotlib(fig) - - -def agent_portrayal(agent): - size = 10 - color = "tab:red" - if agent.wealth > 0: - size = 50 - color = "tab:blue" - return {"size": size, "color": color} - -model_params = { - "n": { - "type": "SliderInt", - "value": 50, - "label": "Number of agents:", - "min": 10, - "max": 100, - "step": 1, - }, - "width": 10, - "height": 10, -} - - - - - -page = SolaraViz( - model1, - components=[SpaceGraph, GiniPlot, Histogram], - model_params=model_params, - name="Boltzmann Wealth Model", -) -# This is required to render the visualization in the Jupyter notebook -page - - - - - -Histogram(model1) - - -