# -*- coding: utf-8 -*- """EcosystemModel.py Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/1JJrMjG87PvAWXvZvwn6gZXAHwkhJ58m0 """ # Commented out IPython magic to ensure Python compatibility. # %pip install mesa # Commented out IPython magic to ensure Python compatibility. # %pip install panel # Commented out IPython magic to ensure Python compatibility. # %pip install networkx # Commented out IPython magic to ensure Python compatibility. # %pip install miepython !kill -9 $(lsof -t -i:8521) #importing the random module import random #defining the population from where sample will be created population = list(range(0, 12)) #defining the size of sample sample_size = 5 #perform simple random sampling by using the random.sample() function sample = random.sample(population, sample_size) #it will print 10 random numbers within the range provided print("Simple random sampling of 5 numbers are: ", sample) ##output: ##Simple random sampling of 10 numbers are: [40, 34, 60, 96, 8, 95, 94, 73, 93, 26] """###Agent Based Model""" import mesa import random import numpy as np from mesa import Agent, Model from mesa.datacollection import DataCollector from mesa.space import MultiGrid from mesa.time import RandomActivation from mesa.visualization.ModularVisualization import ModularServer from mesa.visualization.modules import CanvasGrid, ChartModule from mesa.visualization.UserParam import Slider from mesa.visualization.UserParam import Choice n_ecosystem_starts = 0 GRASSY_AREAS = 1 class Spider(Agent): def __init__(self, unique_id, model, age, fecundity, growth): super().__init__(unique_id, model) self.age = age self.satiation = 20 self.fecundity = fecundity self.growth_rate = growth def step(self): self.age += 1 self.satiation -= 1 self.move() self.grow() # Check if self.pos is not None before proceeding if self.pos is not None: lights_in_cells =self.model.grid.get_cell_list_contents([self.pos]) self.light_interaction(lights_in_cells) # Check satiation only if self.pos is not None if self.satiation <= 0: self.die() def move(self): possible_steps=self.model.grid.get_neighborhood(self.pos, moore=True, include_center=False ) new_position = self.random.choice(possible_steps) if self.model.grid.is_cell_empty(new_position): self.model.grid.move_agent(self, new_position) else: cellmates =self.model.grid.get_cell_list_contents([new_position]) for mate in cellmates: if isinstance(mate, Prey): self.satiation -= 10 mate.remove() self.model.grid.remove_agent(mate) def grow(self): if self.age >= 10 and self.random.random() < self.fecundity: self.reproduce() if self.age >= 20: self.die() def reproduce(self): empty_neighbors = [cell for cell in self.model.grid.get_neighborhood(self.pos, moore=True, include_center=False) if self.model.grid.is_cell_empty(cell)] if empty_neighbors: new_position = self.random.choice(empty_neighbors) new_spider = Spider(self.model.next_id(), self.model, age=0, fecundity=self.fecundity, growth=self.growth_rate) self.model.grid.place_agent(new_spider, new_position) self.model.schedule.add(new_spider) def light_interaction(self, lights_in_cells): if self.pos is not None: # Add this check to ensure the position is not None for light in lights_in_cells: if isinstance(light, Lights): self.satiation += 10 if light.diameter > 0: neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False, radius=light.diameter) for neighbor in neighbors: if isinstance(neighbor, Spider) and neighbor.pos is not None: neighbor.age *= 2 # Double the growth rate for spider neighbors def die(self): self.model.grid.remove_agent(self) self.model.schedule.remove(self) class Prey(Agent): def __init__(self, unique_id, model, age, survival): super().__init__(unique_id, model) self.age = age # self.grid = mesa.space.MultiGrid(width, height, True) self.survival = survival def step(self): self.age += 1 self.move() if any(light for light in self.model.grid.get_neighbors(self.pos, radius=1, moore=True, include_center=False) if isinstance(light, Lights) and light.active and light.intensity > 43): self.move_away() # Example method for moving away from intense light else: self.move() # Regular movement lights_in_range = self.model.grid.get_neighbors(self.pos, radius=1, moore=True, include_center=False) for light in lights_in_range: if isinstance(light, Lights) and 380 <= light.spectrum <= 565: # Logic for prey being attracted to or avoiding light pass if self.age >= 24: self.model.schedule.remove(self) self.model.grid.remove_agent(self) elif self.age >= 5 and self.random.random() < 0.1: # Example: reproduce starting at age 5 with a 10% chance each step self.reproduce() 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 reproduce(self): possible_moves = self.model.grid.get_neighborhood( self.pos, moore=True, include_center=False ) empty_neighbors = [cell for cell in possible_moves if self.model.grid.is_cell_empty(cell)] if empty_neighbors: new_position = self.random.choice(empty_neighbors) new_prey = Prey(self.model.next_id(), self.model, age=0, survival=self.survival) self.model.grid.place_agent(new_prey, new_position) self.model.schedule.add(new_prey) def eat_grass(self): this_cell = self.model.grid.get_cell_list_contents([self.pos]) grasses = [obj for obj in this_cell if isinstance(obj, Grasses)] for grass in grasses: if grass.current_grass > 0: grass.get_eaten(0.2) # Prey eats some amount of grass class Lights(Agent): def __init__(self, unique_id, model, diameter, spectrum, intensity, scattering, duration, active=True): super().__init__(unique_id, model) self.diameter = diameter self.spectrum = spectrum self.intensity = intensity # Lux of light self.scattering = scattering # "Mie" or "Rayleigh" self.duration = duration # Time the light is active self.active = active # def step(self): # # if self.model.schedule.steps % 20 < 10: # # self.intensity = 1 # Daytime # # else: # # self.intensity = 5 # Nighttime def attract_insects(self): if isinstance(agent, property): if 380 <= self.spectrum <= 565: distance = self.model.grid.get_distance(agent.pos, self.pos) if distance <= self.diameter: agent.move_towards_light(self.pos) elif 565 < self.spectrum <= 750: pass def duration(self): while 380 <= self.wavelength <= 565: if self.pos is not None: # Add this check to ensure the position is not None for light in lights_in_cells: if isinstance(light, Lights): self.Prey -= 2 if light.diameter > 0: neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False, radius=light.diameter) for neighbor in neighbors: if isinstance(neighbor, Prey) and neighbor.pos is not None: neighbor.survival *= .5 # Halve the growth rate for spider neighbors class Grasses(Agent): def __init__(self, unique_id, model): super().__init__(unique_id, model) self.growth_rate = 0.1 # Define how quickly the grass grows self.max_grass = 1.0 # Define maximum grass level self.current_grass = 0.5 # Start with some initial grass self.reproduction_rate = 0.05 # Chance of reproducing each step if conditions met def step(self): if self.current_grass < self.max_grass: self.current_grass += self.growth_rate self.current_grass = min(self.max_grass, self.current_grass) # Check if the grass can reproduce if self.current_grass >= self.max_grass: if random.random() < self.reproduction_rate: self.reproduce() def reproduce(self): new_grass = Grasses(self.model.next_id(), self.model) x, y = self.pos available_positions = self.model.grid.get_neighborhood((x, y), moore=True, include_center=False) available_positions = [pos for pos in available_positions if self.model.grid.is_cell_empty(pos)] if available_positions: new_pos = self.random.choice(available_positions) self.model.grid.place_agent(new_grass, new_pos) self.model.schedule.add(new_grass) def get_eaten(self, amount): self.current_grass -= amount if self.current_grass <= 0: self.die() def die(self): self.model.grid.remove_agent(self) self.model.schedule.remove(self) class Environment(MultiGrid): def out_of_bounds(self, pos): if pos is not None: # Add a check to ensure pos is not None x, y = pos # Unpack the coordinates return x < 0 or x >= self.width or y < 0 or y >= self.height else: return True # Return True if pos is None class EcosystemModel(Model): def __init__(self, num_spiders, num_prey, num_lights, num_grasses, spider_fecundity, spider_growth, prey_survival, lights_spectrum, lights_intensity, lights_scattering, lights_duration, lights_diameter, width, height): super().__init__() global n_ecosystem_starts print('before: n_ecosystem_starts:', n_ecosystem_starts) n_ecosystem_starts += 1 self.schedule = RandomActivation(self) self.grid = Environment(width, height, True) self.num_spiders = num_spiders self.num_prey = num_prey self.num_grasses = num_grasses self.num_lights = num_lights self.spider_fecundity = spider_fecundity self.spider_growth = spider_growth self.prey_survival = prey_survival self.lights_spectrum = lights_spectrum self.lights_duration = lights_duration self.lights_intensity = lights_intensity self.lights_scattering = lights_scattering self.lights_diameter = lights_diameter self.running = True self.datacollector = DataCollector( model_reporters={"Spiders": lambda m: sum(isinstance(agent, Spider) for agent in self.schedule.agents), "Prey": lambda m: sum(isinstance(agent, Prey) for agent in self.schedule.agents), #"Lights": lambda m: sum(isinstance(agent, Lights) for agent in self.schedule.agents), "Grasses": lambda m: sum(isinstance(agent, Grasses) for agent in self.schedule.agents) } ) for _i in range(self.num_spiders): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) spider = Spider(self.next_id(), self, age=0, fecundity=self.spider_fecundity, growth=self.spider_growth) self.grid.place_agent(spider, (x, y)) self.schedule.add(spider) for _i in range(self.num_prey): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) prey = Prey(self.next_id(), self, age=0, survival=self.prey_survival) self.grid.place_agent(prey, (x, y)) self.schedule.add(prey) print('ADDED_PREY:', prey.unique_id) for _i in range(self.num_grasses): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) grasses = Grasses(self.next_id(), self) self.grid.place_agent(grasses, (x, y)) self.schedule.add(grasses) print('ADDED_Grasses:', grasses.unique_id) for _i in range(self.num_lights): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) lights = Lights(self.next_id(), self, spectrum=lights_spectrum, intensity=lights_intensity, scattering=lights_scattering, duration=lights_duration, diameter=lights_diameter) self.grid.place_agent(lights, (x, y)) self.schedule.add(lights) print('ADDED_Lights:', lights.unique_id) print('=====================================') def step(self): print("Ecosystem Step called") self.datacollector.collect(self) self.schedule.step() params = { "num_prey": Slider('Number of Prey', 100, 10, 300), "num_spiders": Slider('Number of Spiders', 100, 10, 300), "num_grasses": Slider('Number of Grasses', 100, 10, 300), "num_lights": Slider('Number of Lights', 19, 10, 19), "spider_fecundity": Slider('Spider Fecundity', 0.5, 0, 1, step=int(0.01)), "spider_growth": Slider('Spider Growth Rate', 1, 0, 5, step=int(0.01)), "prey_survival": Slider('Prey Survival', 0.5, 0, 1, step=int(0.01)), "lights_spectrum": Slider('Lights Spectrum', 380, 0, 750), #step=int(0.01)), "lights_duration": Slider('Lights Duration', 1, 0, 12), #step=int(0.01)) "lights_intensity": Slider('Lights Intensity', 1, 0, 44), #step=int(0.01)), "lights_scattering": Choice('Light Scattering', 'Lights Scattering', choices=['Mie', 'Rayleigh']), "lights_diameter": Slider('Lights Diameter', 1, 0, 5), #step=int(0.01)), "width": 50, "height": 40 } def agent_portrayal(agent): portrayal = { "Shape": "circle", "Filled": "true", "Layer": 0, "r": 0.75, } if isinstance(agent, Spider): portrayal["Color"] = "green" if 10 <= agent.age <= 20: portrayal["Color"] = "LimeGreen" # Reproductive age if agent.age >= 20: portrayal["Color"] = "red" # Near end of lifespan elif isinstance(agent, Prey): portrayal["Color"] = "blue" elif isinstance(agent, Grasses): portrayal["Color"] = "pink" elif isinstance(agent, Lights): portrayal["Color"] = "yellow" portrayal["r"] = 0.5 # Different radius for lights to distinguish them portrayal["Color"] = "#FFFF00" if agent.intensity > 3 else "#0000FF" # Yellow for high intensity, blue for low portrayal["r"] = 0.2 + agent.intensity # Larger radius for higher intensity else: portrayal["Color"] = "black" # Fallback color for unidentified agent types # Assign position if available if hasattr(agent, 'pos') and agent.pos: portrayal["x"] = agent.pos[0] portrayal["y"] = agent.pos[1] return portrayal def main(): grid = CanvasGrid(agent_portrayal, params["width"], params["height"], 20*params["width"], 20*params["height"]) chart = ChartModule([{"Label": "Spiders", "Color": "green"}], data_collector_name='datacollector') chart_1 = ChartModule([{"Label": "Prey", "Color": "blue"}], data_collector_name='datacollector') chart_2 = ChartModule([{"Label": "Lights", "Color": "yellow"}], data_collector_name='datacollector') chart_3 = ChartModule([{"Label": "Grasses", "Color": "pink"}], data_collector_name='datacollector') server = ModularServer(EcosystemModel, [grid, chart, chart_1, chart_2, chart_3], "Ecosystem Model", model_params=params) server.launch() def spider_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Spider): sum += 1 return sum # sum(1 for agent in model.schedule.agents if isinstance(agent, Spider))}) def prey_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Prey): sum += 1 return sum # sum(1 for agent in model.schedule.agents if isinstance(agent, Spider))}) # if __name__ == '__main__': # main() # steps = 10 # model = EcosystemModel(300, 100, 18, 50, 1, 0.1, 5, 10, 10, 20, 0.5, 2, 40, 50) # for i in range(steps): # model.step() # out = model.datacollector.get_agent_vars_dataframe().groupby('Step').sum() # out def get_totals_by_step(model): """Extract the total counts of spiders, prey, and grasses at each step.""" model_data = model.datacollector.get_model_vars_dataframe() return model_data import mesa import random import numpy as np from mesa import Agent, Model from mesa.datacollection import DataCollector from mesa.space import MultiGrid from mesa.time import RandomActivation from mesa.visualization.ModularVisualization import ModularServer from mesa.visualization.modules import CanvasGrid, ChartModule from mesa.visualization.UserParam import Slider from mesa.visualization.UserParam import Choice n_ecosystem_starts = 0 GRASSY_AREAS = 1 class Spider(Agent): def __init__(self, unique_id, model, age, fecundity, growth): super().__init__(unique_id, model) self.age = age self.satiation = 20 self.fecundity = fecundity self.growth_rate = growth def step(self): self.age += 1 self.satiation -= 1 self.move() self.grow() # Check if self.pos is not None before proceeding if self.pos is not None: lights_in_cells =self.model.grid.get_cell_list_contents([self.pos]) self.light_interaction(lights_in_cells) # Check satiation only if self.pos is not None if self.satiation <= 0: self.die() def move(self): possible_steps=self.model.grid.get_neighborhood(self.pos, moore=True, include_center=False ) new_position = self.random.choice(possible_steps) if self.model.grid.is_cell_empty(new_position): self.model.grid.move_agent(self, new_position) else: cellmates =self.model.grid.get_cell_list_contents([new_position]) for mate in cellmates: if isinstance(mate, Prey): self.satiation -= 10 mate.remove() self.model.grid.remove_agent(mate) def grow(self): if self.age >= 10 and self.random.random() < self.fecundity: self.reproduce() if self.age >= 20: self.die() def reproduce(self): empty_neighbors = [cell for cell in self.model.grid.get_neighborhood(self.pos, moore=True, include_center=False) if self.model.grid.is_cell_empty(cell)] if empty_neighbors: new_position = self.random.choice(empty_neighbors) new_spider = Spider(self.model.next_id(), self.model, age=0, fecundity=self.fecundity, growth=self.growth_rate) self.model.grid.place_agent(new_spider, new_position) self.model.schedule.add(new_spider) def light_interaction(self, lights_in_cells): if self.pos is not None: # Add this check to ensure the position is not None for light in lights_in_cells: if isinstance(light, Lights): self.satiation += 10 if light.diameter > 0: neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False, radius=light.diameter) for neighbor in neighbors: if isinstance(neighbor, Spider) and neighbor.pos is not None: neighbor.age *= 2 # Double the growth rate for spider neighbors def die(self): self.model.grid.remove_agent(self) self.model.schedule.remove(self) class Prey(Agent): def __init__(self, unique_id, model, age, survival): super().__init__(unique_id, model) self.age = age # self.grid = mesa.space.MultiGrid(width, height, True) self.survival = survival def step(self): self.age += 1 self.move() if any(light for light in self.model.grid.get_neighbors(self.pos, radius=1, moore=True, include_center=False) if isinstance(light, Lights) and light.active and light.intensity > 43): self.move_away() # Example method for moving away from intense light else: self.move() # Regular movement lights_in_range = self.model.grid.get_neighbors(self.pos, radius=1, moore=True, include_center=False) for light in lights_in_range: if isinstance(light, Lights) and 380 <= light.spectrum <= 565: # Logic for prey being attracted to or avoiding light pass if self.age >= 24: self.model.schedule.remove(self) self.model.grid.remove_agent(self) elif self.age >= 5 and self.random.random() < 0.1: # Example: reproduce starting at age 5 with a 10% chance each step self.reproduce() 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 reproduce(self): possible_moves = self.model.grid.get_neighborhood( self.pos, moore=True, include_center=False ) empty_neighbors = [cell for cell in possible_moves if self.model.grid.is_cell_empty(cell)] if empty_neighbors: new_position = self.random.choice(empty_neighbors) new_prey = Prey(self.model.next_id(), self.model, age=0, survival=self.survival) self.model.grid.place_agent(new_prey, new_position) self.model.schedule.add(new_prey) def eat_grass(self): this_cell = self.model.grid.get_cell_list_contents([self.pos]) grasses = [obj for obj in this_cell if isinstance(obj, Grasses)] for grass in grasses: if grass.current_grass > 0: grass.get_eaten(0.2) # Prey eats some amount of grass class Lights(Agent): def __init__(self, unique_id, model, diameter, spectrum, intensity, scattering, duration, active=True): super().__init__(unique_id, model) self.diameter = diameter self.spectrum = spectrum self.intensity = intensity # Lux of light self.scattering = scattering # "Mie" or "Rayleigh" self.duration = duration # Time the light is active self.active = active # def step(self): # # if self.model.schedule.steps % 20 < 10: # # self.intensity = 1 # Daytime # # else: # # self.intensity = 5 # Nighttime def attract_insects(self): if isinstance(agent, property): if 380 <= self.spectrum <= 565: distance = self.model.grid.get_distance(agent.pos, self.pos) if distance <= self.diameter: agent.move_towards_light(self.pos) elif 565 < self.spectrum <= 750: pass def duration(self): while 380 <= self.wavelength <= 565: if self.pos is not None: # Add this check to ensure the position is not None for light in lights_in_cells: if isinstance(light, Lights): self.Prey -= 2 if light.diameter > 0: neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False, radius=light.diameter) for neighbor in neighbors: if isinstance(neighbor, Prey) and neighbor.pos is not None: neighbor.survival *= .5 # Halve the growth rate for spider neighbors class Grasses(Agent): def __init__(self, unique_id, model): super().__init__(unique_id, model) self.growth_rate = 0.1 # Define how quickly the grass grows self.max_grass = 1.0 # Define maximum grass level self.current_grass = 0.5 # Start with some initial grass self.reproduction_rate = 0.05 # Chance of reproducing each step if conditions met def step(self): if self.current_grass < self.max_grass: self.current_grass += self.growth_rate self.current_grass = min(self.max_grass, self.current_grass) # Check if the grass can reproduce if self.current_grass >= self.max_grass: if random.random() < self.reproduction_rate: self.reproduce() def reproduce(self): new_grass = Grasses(self.model.next_id(), self.model) x, y = self.pos available_positions = self.model.grid.get_neighborhood((x, y), moore=True, include_center=False) available_positions = [pos for pos in available_positions if self.model.grid.is_cell_empty(pos)] if available_positions: new_pos = self.random.choice(available_positions) self.model.grid.place_agent(new_grass, new_pos) self.model.schedule.add(new_grass) def get_eaten(self, amount): self.current_grass -= amount if self.current_grass <= 0: self.die() def die(self): self.model.grid.remove_agent(self) self.model.schedule.remove(self) class Environment(MultiGrid): def out_of_bounds(self, pos): if pos is not None: # Add a check to ensure pos is not None x, y = pos # Unpack the coordinates return x < 0 or x >= self.width or y < 0 or y >= self.height else: return True # Return True if pos is None class EcosystemModel(Model): def __init__(self, num_spiders, num_prey, num_lights, num_grasses, spider_fecundity, spider_growth, prey_survival, lights_spectrum, lights_intensity, lights_scattering, lights_duration, lights_diameter, width, height): super().__init__() global n_ecosystem_starts print('before: n_ecosystem_starts:', n_ecosystem_starts) n_ecosystem_starts += 1 self.schedule = RandomActivation(self) self.grid = Environment(width, height, True) self.num_spiders = num_spiders self.num_prey = num_prey self.num_grasses = num_grasses self.num_lights = num_lights self.spider_fecundity = spider_fecundity self.spider_growth = spider_growth self.prey_survival = prey_survival self.lights_spectrum = lights_spectrum self.lights_duration = lights_duration self.lights_intensity = lights_intensity self.lights_scattering = lights_scattering self.lights_diameter = lights_diameter self.running = True self.datacollector = DataCollector( model_reporters={"Spiders": lambda m: sum(isinstance(agent, Spider) for agent in self.schedule.agents), "Prey": lambda m: sum(isinstance(agent, Prey) for agent in self.schedule.agents), #"Lights": lambda m: sum(isinstance(agent, Lights) for agent in self.schedule.agents), "Grasses": lambda m: sum(isinstance(agent, Grasses) for agent in self.schedule.agents) } ) for _i in range(self.num_spiders): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) spider = Spider(self.next_id(), self, age=0, fecundity=self.spider_fecundity, growth=self.spider_growth) self.grid.place_agent(spider, (x, y)) self.schedule.add(spider) for _i in range(self.num_prey): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) prey = Prey(self.next_id(), self, age=0, survival=self.prey_survival) self.grid.place_agent(prey, (x, y)) self.schedule.add(prey) print('ADDED_PREY:', prey.unique_id) for _i in range(self.num_grasses): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) grasses = Grasses(self.next_id(), self) self.grid.place_agent(grasses, (x, y)) self.schedule.add(grasses) print('ADDED_Grasses:', grasses.unique_id) for _i in range(self.num_lights): x = self.random.randrange(self.grid.width) y = self.random.randrange(self.grid.height) lights = Lights(self.next_id(), self, spectrum=lights_spectrum, intensity=lights_intensity, scattering=lights_scattering, duration=lights_duration, diameter=lights_diameter) self.grid.place_agent(lights, (x, y)) self.schedule.add(lights) print('ADDED_Lights:', lights.unique_id) print('=====================================') def step(self): print("Ecosystem Step called") self.datacollector.collect(self) self.schedule.step() params = { "num_prey": Slider('Number of Prey', 100, 10, 300), "num_spiders": Slider('Number of Spiders', 100, 10, 300), "num_grasses": Slider('Number of Grasses', 100, 10, 300), "num_lights": Slider('Number of Lights', 19, 10, 19), "spider_fecundity": Slider('Spider Fecundity', 0.5, 0, 1, step=int(0.01)), "spider_growth": Slider('Spider Growth Rate', 1, 0, 5, step=int(0.01)), "prey_survival": Slider('Prey Survival', 0.5, 0, 1, step=int(0.01)), "lights_spectrum": Slider('Lights Spectrum', 380, 0, 750), #step=int(0.01)), "lights_duration": Slider('Lights Duration', 1, 0, 12), #step=int(0.01)) "lights_intensity": Slider('Lights Intensity', 1, 0, 44), #step=int(0.01)), "lights_scattering": Choice('Light Scattering', 'Lights Scattering', choices=['Mie', 'Rayleigh']), "lights_diameter": Slider('Lights Diameter', 1, 0, 5), #step=int(0.01)), "width": 50, "height": 40 } def agent_portrayal(agent): portrayal = { "Shape": "circle", "Filled": "true", "Layer": 0, "r": 0.75, } if isinstance(agent, Spider): portrayal["Color"] = "green" if 10 <= agent.age <= 20: portrayal["Color"] = "LimeGreen" # Reproductive age if agent.age >= 20: portrayal["Color"] = "red" # Near end of lifespan elif isinstance(agent, Prey): portrayal["Color"] = "blue" elif isinstance(agent, Grasses): portrayal["Color"] = "pink" elif isinstance(agent, Lights): portrayal["Color"] = "yellow" portrayal["r"] = 0.5 # Different radius for lights to distinguish them portrayal["Color"] = "#FFFF00" if agent.intensity > 3 else "#0000FF" # Yellow for high intensity, blue for low portrayal["r"] = 0.2 + agent.intensity # Larger radius for higher intensity else: portrayal["Color"] = "black" # Fallback color for unidentified agent types # Assign position if available if hasattr(agent, 'pos') and agent.pos: portrayal["x"] = agent.pos[0] portrayal["y"] = agent.pos[1] return portrayal def main(): grid = CanvasGrid(agent_portrayal, params["width"], params["height"], 20*params["width"], 20*params["height"]) chart = ChartModule([{"Label": "Spiders", "Color": "green"}], data_collector_name='datacollector') chart_1 = ChartModule([{"Label": "Prey", "Color": "blue"}], data_collector_name='datacollector') chart_2 = ChartModule([{"Label": "Lights", "Color": "yellow"}], data_collector_name='datacollector') chart_3 = ChartModule([{"Label": "Grasses", "Color": "pink"}], data_collector_name='datacollector') server = ModularServer(EcosystemModel, [grid, chart, chart_1, chart_2, chart_3], "Ecosystem Model", model_params=params) server.launch() def spider_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Spider): sum += 1 return sum # sum(1 for agent in model.schedule.agents if isinstance(agent, Spider))}) def prey_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Prey): sum += 1 return sum # sum(1 for agent in model.schedule.agents if isinstance(agent, Spider))}) # if __name__ == '__main__': # main() # steps = 10 # model = EcosystemModel(300, 100, 18, 50, 1, 0.1, 5, 10, 10, 20, 0.5, 2, 40, 50) # for i in range(steps): # model.step() # out = model.datacollector.get_agent_vars_dataframe().groupby('Step').sum() # out def get_totals_by_step(model): """Extract the total counts of spiders, prey, and grasses at each step.""" model_data = model.datacollector.get_model_vars_dataframe() return model_data model = EcosystemModel(100, 100, 18, 100, 565, 6, 22, 2, 10, 20, 0.5, 2, 40, 50) for i in range(15): # Running for 10 steps model.step() totals = get_totals_by_step(model) print(totals) import matplotlib.pyplot as plt import pandas as pd plt.plot(totals) plt.plot(label='Spiders', color='green') plt.plot(label='Prey', color='blue') plt.plot(label='Grasses', color='brown') plt.xlabel('Simulation Step') # Label on X-axis plt.ylabel('Count') # Label on Y-axis plt.title('Agent Counts Over Time') # Title of the graph plt.legend() # Add a legend plt.grid(True) # Add gridlines plt.show() totals.to_csv('data.csv') """####Network Representation""" import networkx as nx import time, enum, math import numpy as np import pandas as pd import pylab as plt import matplotlib.pyplot as plt import networkx as nx import panel as pn import random from matplotlib.colors import ListedColormap, LinearSegmentedColormap from panel import widgets as pnw from mesa import Agent, Model from mesa.datacollection import DataCollector from mesa.space import NetworkGrid from mesa.time import RandomActivation n_ecosystem_starts = 0 GRASSY_AREAS = 1 class Spider(Agent): def __init__(self, unique_id, model, age, fecundity, growth): super().__init__(unique_id, model) self.age = age self.satiation = 20 self.fecundity = fecundity self.growth_rate = growth def step(self): self.age += 1 self.satiation -= 1 self.move() self.grow() # Check if self.pos is not None before proceeding if self.pos is not None: lights_in_cells =self.model.grid.get_cell_list_contents([self.pos]) self.light_interaction(lights_in_cells) # Check satiation only if self.pos is not None if self.satiation <= 0: self.die() def move(self): possible_steps=self.model.grid.get_neighborhood(self.pos, include_center=False ) new_position = self.random.choice(possible_steps) if self.model.grid.is_cell_empty(new_position): self.model.grid.move_agent(self, new_position) else: cellmates =self.model.grid.get_cell_list_contents([new_position]) for mate in cellmates: if isinstance(mate, Prey): self.satiation -= 10 mate.remove() self.model.grid.remove_agent(mate) def grow(self): if self.age >= 10 and self.random.random() < self.fecundity: self.reproduce() if self.age >= 20: self.die() def reproduce(self): empty_neighbors = [cell for cell in self.model.grid.get_neighborhood(self.pos, moore=True, include_center=False) if self.model.grid.is_cell_empty(cell)] if empty_neighbors: new_position = self.random.choice(empty_neighbors) new_spider = Spider(self.model.next_id(), self.model, age=0, fecundity=self.fecundity, growth=self.growth_rate) self.model.grid.place_agent(new_spider, new_position) self.model.schedule.add(new_spider) def light_interaction(self, lights_in_cells): if self.pos is not None: # Add this check to ensure the position is not None for light in lights_in_cells: if isinstance(light, Lights): self.satiation += 10 if light.diameter > 0: neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False, radius=light.diameter) for neighbor in neighbors: if isinstance(neighbor, Spider) and neighbor.pos is not None: neighbor.age *= 2 # Double the growth rate for spider neighbors def die(self): self.model.grid.remove_agent(self) self.model.schedule.remove(self) class Prey(Agent): def __init__(self, unique_id, model, age, survival): super().__init__(unique_id, model) self.age = age # self.grid = mesa.space.MultiGrid(width, height, True) self.survival = survival def step(self): self.age += 1 self.move() if any(light for light in self.model.grid.get_neighbors(self.pos, include_center=False) if isinstance(light, Lights) and light.active and light.intensity > 43): self.move_away() # Example method for moving away from intense light else: self.move() # Regular movement lights_in_range = self.model.grid.get_neighbors(self.pos, include_center=False) for light in lights_in_range: if isinstance(light, Lights) and 380 <= light.spectrum <= 565: # Logic for prey being attracted to or avoiding light pass if self.age >= 24: self.model.schedule.remove(self) self.model.grid.remove_agent(self) elif self.age >= 5 and self.random.random() < 0.1: # Example: reproduce starting at age 5 with a 10% chance each step self.reproduce() def move(self): possible_steps = self.model.grid.get_neighborhood( self.pos, include_center=False ) new_position = self.random.choice(possible_steps) self.model.grid.move_agent(self, new_position) def reproduce(self): possible_moves = self.model.grid.get_neighborhood( self.pos, include_center=False ) empty_neighbors = [cell for cell in possible_moves if self.model.grid.is_cell_empty(cell)] if empty_neighbors: new_position = self.random.choice(empty_neighbors) new_prey = Prey(self.model.next_id(), self.model, age=0, survival=self.survival) self.model.grid.place_agent(new_prey, new_position) self.model.schedule.add(new_prey) class Lights(Agent): def __init__(self, unique_id, model, diameter, spectrum, intensity, scattering, duration, active=True): super().__init__(unique_id, model) self.diameter = diameter self.spectrum = spectrum self.intensity = intensity # Lux of light self.scattering = scattering # "Mie" or "Rayleigh" self.duration = duration # Time the light is active self.active = active def step(self): if self.model.schedule.steps % 20 < 10: self.intensity = 1 # Daytime else: self.intensity = 5 # Nighttime def attract_insects(self): if isinstance(agent, property): if 380 <= self.spectrum <= 565: distance = self.model.grid.get_distance(agent.pos, self.pos) if distance <= self.diameter: agent.move_towards_light(self.pos) elif 565 < self.spectrum <= 750: pass def duration(self): while 380 <= self.wavelength <= 565: if self.pos is not None: # Add this check to ensure the position is not None for light in lights_in_cells: if isinstance(light, Lights): self.Prey -= 2 if light.diameter > 0: neighbors = self.model.grid.get_neighbors(self.pos, moore=True, include_center=False, radius=light.diameter) for neighbor in neighbors: if isinstance(neighbor, Prey) and neighbor.pos is not None: neighbor.survival *= .5 # Halve the growth rate for spider neighbors class Grasses(Agent): def __init__(self, unique_id, model): super().__init__(unique_id, model) self.growth_rate = 0.1 # Define how quickly the grass grows self.max_grass = 1.0 # Define maximum grass level self.current_grass = 0.5 # Start with some initial grass self.reproduction_rate = 0.05 # Chance of reproducing each step if conditions met def step(self): if self.current_grass < self.max_grass: self.current_grass += self.growth_rate self.current_grass = min(self.max_grass, self.current_grass) # Check if the grass can reproduce if self.current_grass >= self.max_grass: if random.random() < self.reproduction_rate: self.reproduce() def reproduce(self): new_grass = Grasses(self.model.next_id(), self.model) x, y = self.pos available_positions = self.model.grid.get_neighborhood((x, y), moore=True, include_center=False) available_positions = [pos for pos in available_positions if self.model.grid.is_cell_empty(pos)] if available_positions: new_pos = self.random.choice(available_positions) self.model.grid.place_agent(new_grass, new_pos) self.model.schedule.add(new_grass) def get_eaten(self, amount): self.current_grass -= amount if self.current_grass <= 0: self.die() def die(self): self.model.grid.remove_agent(self) self.model.schedule.remove(self) # def __init__(self, unique_id, model): # super().__init__(unique_id, model) # if random.random() < GRASSY_AREAS: # self.type = 'Grass' # if self.type == 'Grass': # self.grass = 1.0 # else: # self.grass = 0 # def regrow(self): # self.grass += 1 # self.update() # def get_color(self): # if self.grass >= 1: # return "#00FF0" # else: # return "#CAA800" # def update(self): # self.canvas.itemconfig(self.icon, fill=self.get_color()) # def eat(self): # self.grass = 0 # self.update() # step = int(self.model.step_num + GROWTH // AGE_P) # G.append(self) # self.model.grass_prey[step] = G class Environment(NetworkGrid): def out_of_bounds(self, pos): if pos is not None: x, y = pos # Unpack the coordinates return x < 0 or x >= self.width or y < 0 or y >= self.height else: return True # Return True if pos is None class EcosystemModel(Model): grid = None def __init__( self, num_spiders, num_prey, num_lights, num_grasses, lights_spectrum, lights_duration, lights_intensity, lights_scattering, spider_fecundity, spider_growth, prey_survival, lights_, width, height, steps, delay, layout ): super().__init__() self.schedule = RandomActivation(self) self.num_spiders = num_spiders self.num_prey = num_prey self.num_lights = num_lights self.num_grasses = num_grasses self.spider_fecundity = spider_fecundity self.spider_growth = spider_growth self.prey_survival = prey_survival self.lights_spectrum = lights_spectrum self.lights_duration = lights_duration self.lights_intensity = lights_intensity self.lights_scattering = lights_scattering self.steps = steps self.delay = delay self.layout = layout self.G = nx.erdos_renyi_graph(n=self.num_spiders + self.num_prey + self.num_lights + self.num_grasses, p=0.1) self.grid = NetworkGrid(self.G) self.datacollector = DataCollector(model_reporters = {"Spiders": self.count_spiders, "Prey": self.count_prey, "Lights": self.count_lights, "Grasses": self.count_grasses}) self.running = True self.spiders_count = 0 # Create agents for i, node in enumerate(self.G.nodes()): if i < self.num_spiders: a = Spider(i + 1, self, age=0, fecundity=self.spider_fecundity, growth=1) elif i < self.num_spiders + self.num_prey: a = Prey(i + 1, self, age=0, survival=self.prey_survival) elif i < self.num_spiders + self.num_prey + self.num_lights: a = Lights(i + 1, self, diameter=5, spectrum=self.lights_spectrum, intensity=self.lights_intensity, scattering=self.lights_scattering, duration=self.lights_duration) else: a = Grasses(i + 1, self) self.schedule.add(a) # add agent self.grid.place_agent(a, node) def count_spiders(self): return sum(1 for agent in self.schedule.agents if isinstance(agent, Spider)) def count_prey(self): return sum(1 for agent in self.schedule.agents if isinstance(agent, Prey)) def count_lights(self): return sum(1 for agent in self.schedule.agents if isinstance(agent, Lights)) def count_grasses(self): return sum(1 for agent in self.schedule.agents if isinstance(agent, Grasses)) def step(self): self.schedule.step() self.datacollector.collect(self) def plot_network(self): graph = self.G pos = nx.spring_layout(graph, seed=42) plt.figure(figsize=(10, 8)) self.datacollector = DataCollector(agent_reporters={"Spiders": self.count_spiders}) self.schedule.add(self.datacollector) # Plotting lights lights = [agent for agent in self.schedule.agents if isinstance(agent, Lights)] nx.draw_networkx_nodes(graph, pos, nodelist=[agent.unique_id for agent in lights], node_size=100, node_color='yellow') # Plotting prey prey = [agent for agent in self.schedule.agents if isinstance(agent, Prey)] nx.draw_networkx_nodes(graph, pos, nodelist=[agent.unique_id for agent in prey], node_size=100, node_color='green') # Plotting spiders spiders = [agent for agent in self.schedule.agents if isinstance(agent, Spider)] nx.draw_networkx_nodes(graph, pos, nodelist=[agent.unique_id for agent in spiders], node_size=100, node_color='red') #Plotting grasses grasses = [agent for agent in self.schedule.agents if isinstance(agent, Grasses)] nx.draw_networkx_nodes(graph, pos, nodelist=[agent.unique_id for agent in grasses], node_size=100, node_color='pink') # Plotting edges edges = graph.edges() nx.draw_networkx_edges(graph, pos, edgelist=edges, edge_color='gray') plt.title("Ecosystem Network Visualization") plt.show() def main(): model = EcosystemModel(300, 100, 18, 0.2, 1, 0.1, 5, 10, 10, 20, 0.5, 2) for _i in range(50): model.step() def spider_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Spider): sum += 1 return sum def prey_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Prey): sum += 1 def grasses_sum(agent): sum = 0 for a in agent.model.schedule.agents: if isinstance(a, Grasses): sum += 1 return sum # sum(1 for agent in model.schedule.agents if isinstance(agent, Spider))}) if __name__ == '__main__': main() cmap = ListedColormap(["orange", "black", "teal",]) def plot_grid(model,fig,layout='spring',title='Ecosystem Network'): graph = model.G if layout == 'kamada-kawai': pos = nx.kamada_kawai_layout(graph) elif layout == 'circular': pos = nx.circular_layout(graph) else: pos = nx.spring_layout(graph, iterations=5, seed=8) ax=fig.add_subplot(111) plt.clf() plt.title(title) states = [0] * len(graph.nodes()) # Default state for node in graph.nodes(): agents = model.grid.get_cell_list_contents([node]) if agents: agent = agents[0] # Assuming one agent per node for simplicity if hasattr(agent, 'state'): states[node] = int(agent.state) else: states[node] = 0 # Default state if no 'state' attribute cmap = ListedColormap(["orange", "black", "teal"]) # Ensure this matches state logic colors = [cmap(int(state)) for state in states] nx.draw(graph, pos, node_size=100, edge_color='teal', node_color=colors, alpha=0.9, font_size=14) plt.show() #example usage fig, ax=plt.subplots(1,1,figsize=(16,10)) model = EcosystemModel(50, num_prey = 10 , num_grasses = 50, num_lights= 19, lights_=0, spider_fecundity= 5, prey_survival= 5, lights_spectrum = 565 , lights_duration = 6, lights_intensity=22, lights_scattering = 2, width=10, height=10, spider_growth= 5, steps= 5, delay= 5, layout= 5) model.step() f=plot_grid(model,fig,layout='spring') def run_model(num_prey, num_lights, num_spiders, num_grasses, spider_fecundity, prey_survival, lights_spectrum, lights_duration, lights_intensity, lights_scattering, spider_growth, width, height, steps, delay, layout): model = EcosystemModel(num_lights=num_lights, num_prey=num_prey, num_spiders=num_spiders, num_grasses=num_grasses, prey_survival=prey_survival, lights_spectrum=lights_spectrum, lights_duration=lights_duration, lights_intensity=lights_intensity, lights_scattering=lights_scattering, spider_growth=spider_growth, spider_fecundity=spider_fecundity, width=width, height=height, steps=steps, delay=delay, layout=layout) fig1 = plt.Figure(figsize=(8,6)) ax1 = fig1.add_subplot(1,1,1) grid_pane.object = ax1 # Assign the subplot to grid_pane.object fig2 = plt.Figure(figsize=(8,6)) ax2 = fig2.add_subplot(1,1,1) states_pane.object = ax2 # Draw initial grid plot plot_grid(model, grid_fig, layout=layout) # Update the canvas grid_fig.canvas.draw() states_fig.canvas.draw() # Uncomment this line if you have a separate states plot # Step through the model and plot at each step #step through the model and plot at each step for i in range(steps): model.step() plot_grid(model, grid_fig, title='step=%s' %i, layout=layout) grid_fig.canvas.draw() time.sleep(delay) grid_pane=pn.pane.Matplotlib(plt.Figure(),width=500,height=400) states_pane = pn.pane.Matplotlib(plt.Figure(),width=400,height=300) go_btn = pnw.Button(name='run',width=100,button_type='primary') pop_input = pnw.IntSlider(name='population',value=319,start=10,end=1000,step=10,width=100) num_prey_input = pnw.IntSlider(name='num_prey',value=100,start=10,end=200,width=100) num_lights_input = pnw.IntSlider(name='num_lights',value=19,start=10,end=200,width=100) num_spiders_input = pnw.IntSlider(name='num_spiders',value=100,start=10,end=200,width=100) num_grasses_input = pnw.IntSlider(name='num_grasses',value=100,start=10,end=200,width=100) spider_fecundity_input = pnw.IntSlider(name ='spider_fecunidty', value=100, start=10, end=100,width=100) lights_spectrum_input = pnw.IntSlider(name ='lights_spectrum', value=565, start=380, end=750, width=100) lights_duration_input = pnw.IntSlider(name ='lights_duration', value=11, start=0, end=12, width=100) lights_scattering_input = pnw.Select(name='layout',options=['mie_scattering','rayleigh_scattering'],width=100) lights_intensity_input = pnw.IntSlider(name ='lights_intensity', value=20, start=0, end=44, width=100) prey_survival_input = pnw.IntSlider(name ='prey_survival', value=100, start=10, end=100, width=100) spider_growth_input = pnw.IntSlider(name ='spider_growth', value=100, start=10, end=100, width=100) steps_input = pnw.IntSlider(name='steps',value=20,start=5,end=100,width=100) delay_input = pnw.FloatSlider(name='delay',value=.2,start=0,end=3,step=.2,width=100) layout_input = pnw.Select(name='layout',options=['kamada-kawai','circular','spring'],width=100) widgets = pn.WidgetBox(go_btn,pop_input,num_prey_input, num_lights_input,num_spiders_input, num_grasses_input,spider_fecundity_input, spider_growth_input, lights_spectrum_input, lights_duration_input, lights_scattering_input, lights_intensity_input, steps_input, delay_input, layout_input) run_button = pnw.Button(name='Run Simulation', button_type='primary') pn.extension() run_button.on_click(run_model) grid_fig, grid_ax = plt.subplots(1, 1, figsize=(8, 6)) states_fig, states_ax = plt.subplots(1, 1, figsize=(8, 6)) def execute(event): # Clear previous plots grid_ax.clear() states_ax.clear() # Run the model run_model(num_prey_input.value, num_lights_input.value, num_spiders_input.value, num_grasses_input.value, spider_fecundity_input.value, prey_survival_input.value, lights_spectrum_input.value, lights_duration_input.value, lights_scattering_input.value, lights_intensity_input.value, spider_growth_input.value, steps_input.value, delay_input.value, layout_input.value) # Draw the updated plots grid_fig.canvas.draw() states_fig.canvas.draw() # Watch the button click event go_btn.param.watch(execute, 'clicks') pn.Row(pn.Column(widgets),grid_pane,states_pane,sizing_mode='stretch_width') """\""" import pandas as pd lst = dict(nx.degree_centrality(model.G)) lst_2 = dict(nx.betweenness_centrality(model.G)) lst_3 = dict(nx.eigenvector_centrality(model.G)) lst_4 = dict(nx.closeness_centrality(model.G)) df_degree = pd.DataFrame(lst.items(), columns=['node', 'degree_centrality']) ax1 = df_degree.plot.hexbin(x='node', y='degree_centrality', gridsize = 10, cmap = 'viridis') ax5 = df_degree.plot.scatter(x='node', y='degree_centrality', c = 'DarkBlue') df_eig = pd.DataFrame(lst_3.items(), columns=['node', 'eigenvector_centrality']) ax3 = df_eig.plot.hexbin(x='node', y='eigenvector_centrality', gridsize = 10, cmap = 'viridis') ax6 = df_eig.plot.scatter(x='node', y='eigenvector_centrality', c = 'Red') df_close = pd.DataFrame(lst_4.items(), columns=['node', 'closeness_centrality']) ax4 = df_close.plot.hexbin(x='node', y='closeness_centrality', gridsize = 10, cmap = 'viridis') ax7 = df_close.plot.scatter(x='node', y='closeness_centrality', c = 'green') res = 0 for val in lst.values(): res += val # using len() to get total keys for mean computation res = res / len(lst) # printing result print("Degree Centrality : " + str(res)) for val in lst_2.values(): res += val # using len() to get total keys for mean computation res = res / len(lst_2) # printing result print("Betweenness Centrality : " + str(res)) for val in lst_3.values(): res += val # using len() to get total keys for mean computation res = res / len(lst_3) # printing result print("Eigenvector Centrality : " + str(res)) for val in lst_4.values(): res += val # using len() to get total keys for mean computation res = res / len(lst_4) # printing result print("Closeness Centrality : " + str(res)) import pandas lst_2 = dict(nx.betweenness_centrality(model.G)) df_betweenness = pd.DataFrame(lst_2.items(), columns=['nodes', 'betweeness_centrality']) ax2 = df_betweenness.plot.hexbin(x='nodes', y='betweeness_centrality', gridsize = 10, cmap = 'viridis') ax8 = df_betweenness.plot.scatter(x='nodes', y='betweeness_centrality', c = 'purple') import networkx as nx import matplotlib.pyplot as plt import pickle import copy import random import warnings # Commented out IPython magic to ensure Python compatibility. # %matplotlib inline """#Tests""" import networkx as nx #Total edges/links #model.G.number_of_edges(0, 1) #Connectance/connectivity nx.number_connected_components(model.G) L = nx.laplacian_matrix(model.G).toarray() evals, evecs = np.linalg.eig(L) sorted(evals) for edge in model.G.edges: print(edge) nx.algebraic_connectivity(model.G) #Community Detection import networkx as nx import pandas as pd import matplotlib.pyplot as plt # Load graph and find communities using Girvan-Newman G = model.G communities = list(nx.community.girvan_newman(G)) print(len((communities))) # Modularity -> measures the strength of division of a network into modules modularity_df = pd.DataFrame( [ [k + 1, nx.community.modularity(G, communities[k])] for k in range(len(communities)) ], columns=["k", "modularity"], ) # function to create node colour list def create_community_node_colors(graph, communities): number_of_colors = len(communities[0]) colors = ["#D4FCB1", "#CDC5FC", "#FFC2C4", "#F2D140", "#BCC6C8"][:number_of_colors] node_colors = [] for node in graph: current_community_index = 0 for community in communities: if node in community: node_colors.append(colors[current_community_index]) break current_community_index += 1 return node_colors # function to plot graph with node colouring based on communities def visualize_communities(graph, communities, i): node_colors = create_community_node_colors(graph, communities) modularity = round(nx.community.modularity(graph, communities), 6) title = f"Community Visualization of {len(communities)} communities with modularity of {modularity}" pos = nx.spring_layout(graph, k=0.3, iterations=50, seed=2) plt.subplot(3, 1, i) plt.title(title) nx.draw( graph, pos=pos, node_size=1000, node_color=node_colors, with_labels=True, font_size=20, font_color="black", ) fig, ax = plt.subplots(3, figsize=(15, 20)) # Plot graph with colouring based on communities visualize_communities(G, communities[0], 1) visualize_communities(G, communities[3], 2) # Plot change in modularity as the important edges are removed modularity_df.plot.bar( x="k", ax=ax[2], color="#F2D140", title="Community Detection", ) plt.show() #Degree Distribution import networkx as nx import numpy as np import matplotlib.pyplot as plt G = model.G degree_sequence = sorted((d for n, d in G.degree()), reverse=True) dmax = max(degree_sequence) fig = plt.figure("Degree of a random graph", figsize=(8, 8)) # Create a gridspec for adding subplots of different sizes axgrid = fig.add_gridspec(5, 4) ax0 = fig.add_subplot(axgrid[0:3, :]) Gcc = G.subgraph(sorted(nx.connected_components(G), key=len, reverse=True)[0]) pos = nx.spring_layout(Gcc, seed=10396953) nx.draw_networkx_nodes(Gcc, pos, ax=ax0, node_size=20) nx.draw_networkx_edges(Gcc, pos, ax=ax0, alpha=0.4) ax0.set_title("Connected components of G") ax0.set_axis_off() ax1 = fig.add_subplot(axgrid[3:, :2]) ax1.plot(degree_sequence, "b-", marker="o") ax1.set_title("Degree Rank Plot") ax1.set_ylabel("Degree") ax1.set_xlabel("Rank") ax2 = fig.add_subplot(axgrid[3:, 2:]) ax2.bar(*np.unique(degree_sequence, return_counts=True)) ax2.set_title("Degree histogram") ax2.set_xlabel("Degree") ax2.set_ylabel("# of Nodes") fig.tight_layout() plt.show() # Commented out IPython magic to ensure Python compatibility. # %pip install ruptures import pandas as pd import numpy as np import ruptures as rpt import matplotlib.pyplot as plt # Load data data = pd.read_csv('data.csv') print(data) # Reshape data Spiders = data["Spiders"].values.reshape(-1, 1) # Prey = data["Prey"].values.reshape(-1, 1) # Grasses = data["Grasses"].values.reshape(-1, 1) # Define datasets and names datasets = [Spiders]#, Prey, Grasses] dataset_names = ['Spiders']#, 'Prey', 'Grasses'] kernels = ['linear', 'rbf', 'cosine'] # Create figure with subplots fig, axs = plt.subplots(3, 1, figsize=(13.33, 7.5), dpi=96) # Process each dataset with different kernels for i, kernel in enumerate(kernels): axs[i].set_title(f"Kernel model with {kernel} kernel") for data, name in zip(datasets, dataset_names): algo = rpt.KernelCPD(kernel=kernel, min_size=2) algo.fit(data) try: result = algo.predict(n_bkps=2) # Adjusted to likely fewer breakpoints axs[i].plot(data, label=name) for bkp in result: axs[i].axvline(x=bkp, color='k', linestyle='--') except Exception as e: print(f"Error processing {name} with {kernel} kernel: {str(e)}") axs[i].legend() fig.tight_layout() plt.show() import pandas as pd import numpy as np import ruptures as rpt import matplotlib.pyplot as plt # Load data data = pd.read_csv('data.csv') print(data) # Reshape data Prey = data["Prey"].values.reshape(-1, 1) # Prey = data["Prey"].values.reshape(-1, 1) # Grasses = data["Grasses"].values.reshape(-1, 1) # Define datasets and names datasets = [Prey]#, Prey, Grasses] dataset_names = ['Prey']#, 'Prey', 'Grasses'] kernels = ['linear', 'rbf', 'cosine'] # Create figure with subplots fig, axs = plt.subplots(3, 1, figsize=(13.33, 7.5), dpi=96) # Process each dataset with different kernels for i, kernel in enumerate(kernels): axs[i].set_title(f"Kernel model with {kernel} kernel") for data, name in zip(datasets, dataset_names): algo = rpt.KernelCPD(kernel=kernel, min_size=2) algo.fit(data) try: result = algo.predict(n_bkps=3) # Adjusted to likely fewer breakpoints axs[i].plot(data, label=name) for bkp in result: axs[i].axvline(x=bkp, color='k', linestyle='--') except Exception as e: print(f"Error processing {name} with {kernel} kernel: {str(e)}") axs[i].legend() fig.tight_layout() plt.show() import pandas as pd import numpy as np import ruptures as rpt import matplotlib.pyplot as plt # Load data data = pd.read_csv('data.csv') print(data) # Reshape data Grasses = data["Grasses"].values.reshape(-1, 1) # Prey = data["Prey"].values.reshape(-1, 1) # Grasses = data["Grasses"].values.reshape(-1, 1) # Define datasets and names datasets = [Grasses]#, Prey, Grasses] dataset_names = ['Grasses']#, 'Prey', 'Grasses'] kernels = ['linear', 'rbf', 'cosine'] # Create figure with subplots fig, axs = plt.subplots(3, 1, figsize=(13.33, 7.5), dpi=96) # Process each dataset with different kernels for i, kernel in enumerate(kernels): axs[i].set_title(f"Kernel model with {kernel} kernel") for data, name in zip(datasets, dataset_names): algo = rpt.KernelCPD(kernel=kernel, min_size=2) algo.fit(data) try: result = algo.predict(n_bkps=3) # Adjusted to likely fewer breakpoints axs[i].plot(data, label=name) for bkp in result: axs[i].axvline(x=bkp, color='k', linestyle='--') except Exception as e: print(f"Error processing {name} with {kernel} kernel: {str(e)}") axs[i].legend() fig.tight_layout() plt.show() import numpy as np #Update with actual points x = np.array([1, 2, 3, 4, 5]) y = np.array([100,100,99,98,98,98]) index = 3 h = x[1] - x[0] # Increment between adjacent x values derivative_at_index = (y[index + 1] - y[index]) / h print("The derivative at index", index, "is approximately:", derivative_at_index) if derivative_at_index > 0: print("positive change") else: print("negative change") # Commented out IPython magic to ensure Python compatibility. # %pip install ecopy import pandas as pd data = pd.read_csv('data.csv') species_counts = data.sum().to_dict() print(species_counts) def simpson_di(data): """ Calculate the Simpson Diversity Index from a dictionary of species counts. """ N = sum(data.values()) # Total number of organisms if N == 0: return 0 # Prevent division by zero return sum((n / N) ** 2 for n in data.values() if n != 0) diversity_index = simpson_di(species_counts) # Print the result print("Simpson Diversity Index:", diversity_index) import random import networkx as nx import matplotlib.pyplot as plt def attack_random_edges(graph, num_edges_to_attack): if num_edges_to_attack > graph.number_of_edges(): print("Error: More edges requested to attack than exist in the graph.") # Adjusting number of edges to attack if the requested number is too high num_edges_to_attack = graph.number_of_edges() # Randomly select edges to attack edges_to_attack = random.sample(graph.edges(), num_edges_to_attack) # Track impacted edges based on node degree after removal impacted_edges = [] for edge in edges_to_attack: graph.remove_edge(*edge) # permanently remove the edge for node in edge: if graph.degree[node] == 1 and list(graph.neighbors(node)): # Check if the node becomes a leaf node neighbor = next(graph.neighbors(node), None) if neighbor is not None: # Ensure there is a neighbor left impacted_edge = (node, neighbor) impacted_edges.append(impacted_edge) # Optionally, keep track of which edges were attacked, if needed attacked_edges_info = [(u, v) for u, v in edges_to_attack] # Return the list of attacked and impacted edges return attacked_edges_info, impacted_edges # Assuming EcosystemModel is defined elsewhere and correctly initializes the graph # Example usage: G = model.G # Create the model and access the graph # Attack 5 random edges print("Edges before attack:", len(G.edges())) attacked_edges, impacted_edges = attack_random_edges(G, 268) print("Edges after attack:", len(G.edges())) # Compute positions for visualization after the attack pos = nx.spring_layout(G) # Compute positions for visualization # Visualize the graph nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray') plt.title("Graph After Attacks") plt.show() # Checking the largest connected component largest_cc = max(nx.connected_components(G), key=len) print("Largest connected component nodes:", len(largest_cc)) import random import networkx as nx import matplotlib.pyplot as plt def attack_random_edges(graph, num_edges_to_attack): if num_edges_to_attack > graph.number_of_edges(): print("Error: More edges requested to attack than exist in the graph.") num_edges_to_attack = graph.number_of_edges() # Limiting to max available edges # Convert graph edges to a list before sampling to avoid deprecation warning edge_list = list(graph.edges()) edges_to_attack = random.sample(edge_list, num_edges_to_attack) # Track impacted edges based on node degree after removal impacted_edges = [] for edge in edges_to_attack: graph.remove_edge(*edge) # permanently remove the edge for node in edge: # Only check neighbors if the node still exists in the graph if node in graph and graph.degree[node] == 1: neighbors = list(graph.neighbors(node)) if neighbors: # Ensure there's at least one neighbor impacted_edge = (node, neighbors[0]) impacted_edges.append(impacted_edge) # Optionally, keep track of which edges were attacked, if needed attacked_edges_info = [(u, v) for u, v in edges_to_attack] # Return the list of attacked and impacted edges return attacked_edges_info, impacted_edges # Example usage assumes model has been defined and G is accessible model = EcosystemModel(num_spiders=100, num_prey=100, num_lights=19, num_grasses=100, lights_=0, lights_spectrum=565, lights_duration=11, lights_intensity=22, lights_scattering="Rayleigh", spider_fecundity=0.1, spider_growth=0.05, prey_survival=0.8, width=10, height=10, steps=100, delay=1, layout="spring") G = model.G # Access the graph from the model # Attack 5 random edges print("Edges before attack:", G.number_of_edges()) attacked_edges, impacted_edges = attack_random_edges(G, int(0.9*G.number_of_edges())) print("Edges after attack:", G.number_of_edges()) # Compute positions for visualization after the attack pos = nx.spring_layout(G) # Compute positions for visualization # Visualize the graph nx.draw(G, pos, with_labels=True, node_color='yellow', edge_color='black') plt.title("Graph After Attacks") plt.show() # Checking the largest connected component largest_cc = max(nx.connected_components(G), key=len) print("Largest connected component nodes:", len(largest_cc)) import random import networkx as nx import matplotlib.pyplot as plt def attack_random_edges(graph, num_edges_to_attack): if num_edges_to_attack > graph.number_of_edges(): print("Error: More edges requested to attack than exist in the graph.") num_edges_to_attack = graph.number_of_edges() edge_list = list(graph.edges()) edges_to_attack = random.sample(edge_list, num_edges_to_attack) impacted_edges = [] for edge in edges_to_attack: graph.remove_edge(*edge) for node in edge: if node in graph and graph.degree[node] == 1: neighbors = list(graph.neighbors(node)) if neighbors: impacted_edge = (node, neighbors[0]) impacted_edges.append(impacted_edge) attacked_edges_info = [(u, v) for u, v in edges_to_attack] return attacked_edges_info, impacted_edges # Assuming model has been defined and G is accessible G_initial = G.copy() # Keep a copy of the original graph for comparison print("Initial number of edges:", G.number_of_edges()) attacked_edges, impacted_edges = attack_random_edges(G, int(0.8*G.number_of_edges())) print("Number of edges after attack:", G.number_of_edges()) pos_initial = nx.spring_layout(G_initial) plt.figure(figsize=(10, 5)) plt.subplot(121) nx.draw(G_initial, pos_initial, with_labels=True, node_color='lightblue', edge_color='gray') plt.title("Initial Graph") pos = nx.spring_layout(G) plt.subplot(122) nx.draw(G, pos, with_labels=True, node_color='lightblue', edge_color='gray') plt.title("Graph After Attacks") plt.show() largest_cc = max(nx.connected_components(G), key=len) print("Largest connected component nodes:", len(largest_cc))