def test_not_enough_herbs_to_eat(self): """Tests that the animal eats what is left and nothing more when they cannot fill their F""" animal_list = [{ 'loc': (1, 1), 'pop': [{ 'species': 'Carnivore', 'age': 5, 'weight': 53.3 }, { 'species': 'Herbivore', 'age': 500, 'weight': 20 }, { 'species': 'Herbivore', 'age': 500, 'weight': 20 }] }] a = Island('OOO\nOJO\nOOO') b = Carnivores() c = Herbivores() a.add_animals(animal_list) b.set_new_params({'beta': 1, 'F': 50, 'DeltaPhiMax': 0.0001}) c.calculate_fitness((1, 1), a.herbs) b.calculate_fitness((1, 1), a.carns) b.carnivores_eat((1, 1), a, a.carns) assert len(a.herbs[(1, 1)]) == 0 assert a.carns[(1, 1)][0]['weight'] == 93.3
def test_invalid_moving_carns(self): """ Tests invalid moving is not happening""" population1 = [{ 'loc': (2, 2), 'pop': [{ 'species': 'Carnivore', 'age': 5, 'weight': 13.3 }] }, { 'loc': (2, 2), 'pop': [{ 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }] }] a = Island("OOOOO\nOOMOO\nOOJOO\nOOMOO\nOOJOO") b = Carnivores() c = Herbivores() a.add_animals(population1) b.calculate_fitness((2, 2), a.carns) b.migration_calculations(a, c, a.carns) assert len(a.carns[(2, 2)]) == 9 assert (3, 2) not in a.carns.keys() assert len(b.idx_for_animals_to_remove) == 0 b.migration_execution(a, a.carns) assert len(a.carns[(2, 2)]) == 9
def test_breeding_carnivores(self): """Tests if carnivores can give birth, and that the children get added to the same tile as their parents""" added_list = [{ 'loc': (3, 3), 'pop': [{ 'species': 'Carnivore', 'age': 20, 'weight': 17.3 }, { 'species': 'Carnivore', 'age': 30, 'weight': 19.3 }, { 'species': 'Carnivore', 'age': 10, 'weight': 107.3 }, { 'species': 'Carnivore', 'age': 1, 'weight': 20.3 }] }] a = self.jungle_island_animals()[0] b = Carnivores() a.set_food((3, 3)) a.add_animals(added_list) len_list1 = len(a.carns[(3, 3)]) b.calculate_fitness((3, 3), a.carns) for _ in range(10): b.breeding((3, 3), a, a.carns) len_list2 = len(a.carns[(3, 3)]) assert len_list2 > len_list1
def test_carnivores_eat_sometimes_when_they_have_somewhat_higher_fitness( self): """ Testing that the carnivores do eat with some kind of probability when their fitness is somewhat higher than the herbivores """ animal_list = [{ 'loc': (1, 1), 'pop': [{ 'species': 'Carnivore', 'age': 1, 'weight': 53.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }] }] a = Island('OOO\nOJO\nOOO') b = Carnivores() c = Herbivores() a.add_animals(animal_list) b.set_new_params({'beta': 1, 'F': 50}) c.calculate_fitness((1, 1), a.herbs) b.calculate_fitness((1, 1), a.carns) for _ in range(40): b.carnivores_eat((1, 1), a, a.carns) assert len(a.herbs[(1, 1)]) < 4 assert len(a.herbs[(1, 1)]) != 0
def test_carnivore_leaves_food(self): """Testing that the carnivores stops eating when it has received f amount of food""" animal_list = [{ 'loc': (1, 1), 'pop': [{ 'species': 'Carnivore', 'age': 5, 'weight': 53.3 }, { 'species': 'Carnivore', 'age': 5, 'weight': 53.3 }, { 'species': 'Herbivore', 'age': 500, 'weight': 13.3 }, { 'species': 'Herbivore', 'age': 500, 'weight': 13.3 }, { 'species': 'Herbivore', 'age': 500, 'weight': 13.3 }, { 'species': 'Herbivore', 'age': 500, 'weight': 13.3 }] }] a = Island('OOO\nOJO\nOOO') b = Carnivores() c = Herbivores() a.add_animals(animal_list) b.set_new_params({'beta': 1, 'F': 5, 'DeltaPhiMax': 0.0001}) c.calculate_fitness((1, 1), a.herbs) b.calculate_fitness((1, 1), a.carns) b.carnivores_eat((1, 1), a, a.carns) assert len(a.herbs[(1, 1)]) == 2 assert a.carns[(1, 1)][0]['weight'] == 58.3 assert a.carns[(1, 1)][1]['weight'] == 58.3
def test_carnivores_does_not_eat_with_lower_fitness(self): """Testing that the carnivores do not eat when they have lower fitness than the herbivores""" animal_list = [{ 'loc': (1, 1), 'pop': [{ 'species': 'Carnivore', 'age': 500, 'weight': 53.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }, { 'species': 'Herbivore', 'age': 1, 'weight': 23.3 }] }] a = Island('OOO\nOJO\nOOO') b = Carnivores() c = Herbivores() a.add_animals(animal_list) b.set_new_params({'beta': 1, 'F': 50}) c.calculate_fitness((1, 1), a.herbs) b.calculate_fitness((1, 1), a.carns) for _ in range(40): b.carnivores_eat((1, 1), a, a.carns) assert len(a.herbs[(1, 1)]) == 4
def test_default_call(self): """ Testing that that each of the two animal-subclasses are callable and that the default values are set properly """ a = Herbivores() b = Carnivores() assert a.w_birth == 8 assert a.sigma_birth == 1.5 assert a.beta == 0.9 assert a.eta == 0.05 assert a.a_half == 40 assert a.phi_age == 0.2 assert a.w_half == 10 assert a.phi_weight == 0.1 assert a.mu == 0.25 assert a.lambda1 == 1 assert a.gamma == 0.2 assert a.zeta == 3.5 assert a.xi == 1.2 assert a.omega == 0.4 assert a.f == 10 assert b.w_birth == 6 assert b.sigma_birth == 1.0 assert b.beta == 0.75 assert b.eta == 0.125 assert b.a_half == 60 assert b.phi_age == 0.4 assert b.w_half == 4 assert b.phi_weight == 0.4 assert b.mu == 0.4 assert b.lambda1 == 1 assert b.gamma == 0.8 assert b.zeta == 3.5 assert b.xi == 1.1 assert b.omega == 0.9 assert b.f == 50 assert b.deltaphimax == 10
def test_migration_carnivores(self): """Tests that the carnivores migrate and that they do not move before the execution-function is called""" population = [{ 'loc': (3, 2), 'pop': [{ 'species': 'Herbivore', 'age': 5, 'weight': 13.3 }] }, { 'loc': (3, 2), 'pop': [{ 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }] }] population1 = [{ 'loc': (3, 1), 'pop': [{ 'species': 'Carnivore', 'age': 5, 'weight': 13.3 }] }, { 'loc': (3, 1), 'pop': [{ 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }] }] a = Island("OOOOO\nOJJJO\nOJJJO\nOJJJO\nOJJJO\nOOOOO") b = Carnivores() c = Herbivores() a.add_animals(population) a.add_animals(population1) b.calculate_fitness((3, 1), a.carns) b.migration_calculations(a, c, a.carns) assert len(a.carns[(3, 1)]) == 9 assert (3, 2) not in a.carns.keys() assert len(b.idx_for_animals_to_remove) > 0 b.migration_execution(a, a.carns) assert len(a.carns[(3, 2)]) > 0 assert len(a.carns[(3, 1)]) < 9
def test_set_new_params(self): """ Tests setting new parameter for both animal-subclases""" a = Herbivores() b = Carnivores() a.set_new_params({ 'w_birth': 12.0, 'sigma_birth': 1.3, 'beta': 1, 'eta': 0.06, 'a_half': 41.0, 'phi_age': 0.3, 'w_half': 11.0, 'phi_weight': 0.2, 'mu': 0.3, 'lambda': 1.1, 'gamma': 0.3, 'zeta': 3.6, 'xi': 1.3, 'omega': 0.5, 'F': 11.0 }) b.set_new_params({ 'w_birth': 8.0, 'sigma_birth': 1.2, 'beta': 0.9, 'eta': 0.05, 'a_half': 40.0, 'phi_age': 0.2, 'w_half': 10.0, 'phi_weight': 0.1, 'mu': 0.25, 'lambda': 1.0, 'gamma': 0.2, 'zeta': 3.5, 'xi': 1.2, 'omega': 0.4, 'F': 10.0, 'DeltaPhiMax': 11 }) assert a.w_birth == 12 assert a.sigma_birth == 1.3 assert a.beta == 1 assert a.eta == 0.06 assert a.a_half == 41 assert a.phi_age == 0.3 assert a.w_half == 11 assert a.phi_weight == 0.2 assert a.mu == 0.3 assert a.lambda1 == 1.1 assert a.gamma == 0.3 assert a.zeta == 3.6 assert a.xi == 1.3 assert a.omega == 0.5 assert a.f == 11 assert b.w_birth == 8 assert b.sigma_birth == 1.2 assert b.beta == 0.9 assert b.eta == 0.05 assert b.a_half == 40 assert b.phi_age == 0.2 assert b.w_half == 10 assert b.phi_weight == 0.1 assert b.mu == 0.25 assert b.lambda1 == 1.0 assert b.gamma == 0.2 assert b.zeta == 3.5 assert b.xi == 1.2 assert b.omega == 0.4 assert b.f == 10 assert b.deltaphimax == 11
def test_set_new_params_raise_errors(self): """ Tests that it is not possible to create new parameters, or parameters that is out of range""" a = Herbivores() b = Carnivores() with pytest.raises(TypeError): a.set_new_params([1243]) with pytest.raises(TypeError): b.set_new_params([1234]) with pytest.raises(KeyError): a.set_new_params({'W_BIRTH': 1}) with pytest.raises(KeyError): b.set_new_params({'W_BIRTH': 1}) with pytest.raises(ValueError): a.set_new_params({'w_birth': -1}) with pytest.raises(ValueError): b.set_new_params({'w_birth': -1}) with pytest.raises(ValueError): a.set_new_params({'sigma_birth': -1}) with pytest.raises(ValueError): b.set_new_params({'sigma_birth': -1}) with pytest.raises(ValueError): a.set_new_params({'beta': -1}) with pytest.raises(ValueError): b.set_new_params({'beta': -1}) with pytest.raises(ValueError): a.set_new_params({'eta': -1}) with pytest.raises(ValueError): b.set_new_params({'eta': -1}) with pytest.raises(ValueError): a.set_new_params({'a_half': -1}) with pytest.raises(ValueError): b.set_new_params({'a_half': -1}) with pytest.raises(ValueError): a.set_new_params({'phi_age': -1}) with pytest.raises(ValueError): b.set_new_params({'phi_age': -1}) with pytest.raises(ValueError): a.set_new_params({'w_half': -1}) with pytest.raises(ValueError): b.set_new_params({'w_half': -1}) with pytest.raises(ValueError): a.set_new_params({'phi_weight': -1}) with pytest.raises(ValueError): b.set_new_params({'phi_weight': -1}) with pytest.raises(ValueError): a.set_new_params({'mu': -1}) with pytest.raises(ValueError): b.set_new_params({'mu': -1}) with pytest.raises(ValueError): a.set_new_params({'lambda': -1}) with pytest.raises(ValueError): b.set_new_params({'lambda': -1}) with pytest.raises(ValueError): a.set_new_params({'gamma': -1}) with pytest.raises(ValueError): b.set_new_params({'gamma': -1}) with pytest.raises(ValueError): a.set_new_params({'zeta': -1}) with pytest.raises(ValueError): b.set_new_params({'zeta': -1}) with pytest.raises(ValueError): a.set_new_params({'xi': -1}) with pytest.raises(ValueError): b.set_new_params({'xi': -1}) with pytest.raises(ValueError): a.set_new_params({'omega': -1}) with pytest.raises(ValueError): b.set_new_params({'omega': -1}) with pytest.raises(ValueError): a.set_new_params({'F': -1}) with pytest.raises(ValueError): b.set_new_params({'F': -1}) with pytest.raises(ValueError): b.set_new_params({'DeltaPhiMax': -1})
def test_more_migration(self): """Tests that the carnivores migrates to all cells""" population = [{ 'loc': (2, 2), 'pop': [{ 'species': 'Herbivore', 'age': 5, 'weight': 13.3 }] }, { 'loc': (2, 2), 'pop': [{ 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }, { 'species': 'Herbivore', 'age': 4, 'weight': 10 }] }] population1 = [{ 'loc': (2, 2), 'pop': [{ 'species': 'Carnivore', 'age': 5, 'weight': 13.3 }] }, { 'loc': (2, 2), 'pop': [{ 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }, { 'species': 'Carnivore', 'age': 4, 'weight': 10 }] }] a = Island("OOOOO\nOJJJO\nOJJJO\nOJJJO\nOJJJO\nOOOOO") b = Carnivores() c = Herbivores() a.add_animals(population) a.add_animals(population1) for i in range(a.rader): for j in range(a.col): a.set_food((i, j)) b.calculate_fitness((2, 2), a.carns) c.calculate_fitness((2, 2), a.herbs) for _ in range(20): c.migration_calculations(a, a.herbs) c.migration_execution(a, a.herbs) for _ in range(20): b.migration_calculations(a, c, a.carns) b.migration_execution(a, a.carns) for i in range(1, 3): for j in range(1, 3): assert (i, j) in a.carns.keys()
def __init__(self, island_map, ini_pop, seed, ymax_animals=None, cmax_animals=None, img_base=None, img_fmt='png'): """ :param island_map: Multi-line string specifying island geography :param ini_pop: List of dictionaries specifying initial population :param seed: Integer used as random number seed :param ymax_animals: Number specifying y-axis limit for graph showing animal numbers :param cmax_animals: Dict specifying color-code limits for animal densities :param img_base: String with beginning of file name for figures, including path :param img_fmt: String with file type for figures, e.g. 'png' If ymax_animals is None, the y-axis limit should be adjusted automatically. If cmax_animals is None, sensible, fixed default values should be used. cmax_animals is a dict mapping species names to numbers, e.g., {'Herbivore': 50, 'Carnivore': 20} If img_base is None, no figures are written to file. Filenames are formed as '{}_{:05d}.{}'.format(img_base, img_no, img_fmt) where img_no are consecutive image numbers starting from 0. img_base should contain a path and beginning of a file name. """ # variables for code/setup/classes self.ini_pop = ini_pop self.island_map = island_map self.tot_num_years = 0 # variables for movie/save if img_base is not None: self._img_base = img_base else: self._img_base = None self._img_fmt = img_fmt self._img_ctr = 0 # Variables for visualization/plot self.ax1 = None self.ax2 = None self.ax3 = None self.ax4 = None self.line = None self.line2 = None if ymax_animals is None: self.ymax_animals = 20000 else: self.ymax_animals = ymax_animals if cmax_animals is None: self.cmax_animals = {'Herbivore': 100, 'Carnivore': 100} else: self.cmax_animals = cmax_animals # Initialization, setting classes and seed self.island = Island(island_map) self.island.limit_map_vals() self.herbivores = Herbivores() self.carnivores = Carnivores() self.animal = Animal() self.setup_simulation() np.random.seed(seed) random.seed(seed)
class BioSim: def __init__(self, island_map, ini_pop, seed, ymax_animals=None, cmax_animals=None, img_base=None, img_fmt='png'): """ :param island_map: Multi-line string specifying island geography :param ini_pop: List of dictionaries specifying initial population :param seed: Integer used as random number seed :param ymax_animals: Number specifying y-axis limit for graph showing animal numbers :param cmax_animals: Dict specifying color-code limits for animal densities :param img_base: String with beginning of file name for figures, including path :param img_fmt: String with file type for figures, e.g. 'png' If ymax_animals is None, the y-axis limit should be adjusted automatically. If cmax_animals is None, sensible, fixed default values should be used. cmax_animals is a dict mapping species names to numbers, e.g., {'Herbivore': 50, 'Carnivore': 20} If img_base is None, no figures are written to file. Filenames are formed as '{}_{:05d}.{}'.format(img_base, img_no, img_fmt) where img_no are consecutive image numbers starting from 0. img_base should contain a path and beginning of a file name. """ # variables for code/setup/classes self.ini_pop = ini_pop self.island_map = island_map self.tot_num_years = 0 # variables for movie/save if img_base is not None: self._img_base = img_base else: self._img_base = None self._img_fmt = img_fmt self._img_ctr = 0 # Variables for visualization/plot self.ax1 = None self.ax2 = None self.ax3 = None self.ax4 = None self.line = None self.line2 = None if ymax_animals is None: self.ymax_animals = 20000 else: self.ymax_animals = ymax_animals if cmax_animals is None: self.cmax_animals = {'Herbivore': 100, 'Carnivore': 100} else: self.cmax_animals = cmax_animals # Initialization, setting classes and seed self.island = Island(island_map) self.island.limit_map_vals() self.herbivores = Herbivores() self.carnivores = Carnivores() self.animal = Animal() self.setup_simulation() np.random.seed(seed) random.seed(seed) def set_animal_parameters(self, species, params): """ Set parameters for animal species. :param species: String, name of animal species :param params: Dict with valid parameter specification for species """ if species == 'Herbivore': self.herbivores.set_new_params(params) else: self.carnivores.set_new_params(params) def set_landscape_parameters(self, terrain, params): """ Set parameters for landscape types. :param terrain: Tells which terrain shall get new parameters :param params: Dict with valid parameter specification for landscape """ self.island.set_new_params(terrain, params) def setup_simulation(self): """ Function to set up the simulation, sets up the food and inserts the initial population. """ for i in range(self.island.rader): for j in range(self.island.col): self.island.set_food((i, j)) self.island.add_animals(self.ini_pop) def simulate_one_year(self): """ Function used to simulate one year """ for i in range(self.island.rader): for j in range(self.island.col): pos = (i, j) self.island.grow_food(pos) self.herbivores.calculate_fitness(pos, self.island.herbs) self.herbivores.sort_by_fitness(pos, self.island.herbs) self.herbivores.animals_eat(pos, self.island, self.island.herbs) self.herbivores.sort_before_getting_hunted( pos, self.island.herbs) self.carnivores.calculate_fitness(pos, self.island.carns) self.carnivores.sort_by_fitness(pos, self.island.carns) self.carnivores.carnivores_eat(pos, self.island, self.island.carns) self.herbivores.breeding(pos, self.island, self.island.herbs) self.carnivores.calculate_fitness(pos, self.island.carns) self.carnivores.breeding(pos, self.island, self.island.carns) self.herbivores.calculate_fitness(pos, self.island.herbs) self.carnivores.calculate_fitness(pos, self.island.carns) self.herbivores.migration_calculations(self.island, self.island.herbs) self.carnivores.migration_calculations(self.island, self.herbivores, self.island.carns) self.herbivores.migration_execution(self.island, self.island.herbs) self.carnivores.migration_execution(self.island, self.island.carns) for i in range(self.island.rader): for j in range(self.island.col): pos = (i, j) self.herbivores.aging(pos, self.island.herbs) self.carnivores.aging(pos, self.island.carns) self.herbivores.loss_of_weight(pos, self.island.herbs) self.carnivores.loss_of_weight(pos, self.island.carns) self.herbivores.calculate_fitness(pos, self.island.herbs) self.carnivores.calculate_fitness(pos, self.island.carns) self.herbivores.death(pos, self.island.herbs) self.carnivores.death(pos, self.island.carns) def simulate(self, num_years, vis_years=1, img_years=None): """ Function used to simulate num_years, visualizing every vis_years and taking a picture every img_years. :param num_years: Number of years to simulate :param vis_years: Number that indicates how many years between each visualization :param img_years: Number that indicates how many years between taking images, if None a picture will be taken for each visualization """ self._setup_graphics(num_years) for year in range(num_years): if year % vis_years == 0: self._update_graphics() if year % img_years == 0: self._save_graphics() self.simulate_one_year() self.tot_num_years += 1 def add_population(self, population): """ Add a population to the island :param population: List of dictionaries specifying population """ self.island.add_animals(population) def _setup_graphics(self, num_years): """ This function is used to setup the figure of the grapichs, it creates a figure with 4 subplots and initializes the animal lines which are plotted in the upper right subplot. :param num_years: :return: """ fig = plt.figure() axt = fig.add_axes([0.4, 0.8, 0.2, 0.2]) axt.axis('off') self.ax1 = plt.subplot2grid((2, 2), (0, 0)) self.ax2 = plt.subplot2grid((2, 2), (0, 1)) self.ax3 = plt.subplot2grid((2, 2), (1, 0)) self.ax4 = plt.subplot2grid((2, 2), (1, 1)) self.ax2.set_xlim(self.year + 1, self.year + num_years) self.ax2.set_ylim(0, self.ymax_animals) self.line = self.ax2.plot(np.arange(num_years + self.year + 1), np.full(num_years + self.year + 1, np.nan), 'b-')[0] self.line2 = self.ax2.plot(np.arange(num_years + self.year + 1), np.full(num_years + self.year + 1, np.nan), 'r-')[0] def _update_graphics(self): """ Updates graphics with current data. """ plt.suptitle('Years since the simulation started: ' + str(self.year) + ' years') rgb_value = { "O": mcolors.to_rgba("navy"), "J": mcolors.to_rgba("forestgreen"), "S": mcolors.to_rgba("#e1ab62"), "D": mcolors.to_rgba("yellow"), "M": mcolors.to_rgba("lightslategrey") } kart_rgb = [[rgb_value[column] for column in row] for row in self.island_map.split()] self.ax1.imshow(kart_rgb) self.ax1.set_xticks(range(len(kart_rgb[0]))) self.ax1.set_xticklabels(range(1, 1 + len(kart_rgb[0]))) self.ax1.set_yticks(range(len(kart_rgb))) self.ax1.set_yticklabels(range(1, 1 + len(kart_rgb))) self.ax1.axis('scaled') self.ax1.set_title('Map') # Upper right subplot ydata = self.line.get_ydata() ydata2 = self.line2.get_ydata() ydata[self.year] = self.num_animals_per_species['Herbivore'] ydata2[self.year] = self.num_animals_per_species['Carnivore'] self.line.set_ydata(ydata) self.line2.set_ydata(ydata2) self.ax2.set_title('Total number of animals') self.ax3.imshow(self.animal_distribution_for_plot[:, :, 0], 'Greens', vmax=self.cmax_animals['Herbivore']) self.ax3.set_xticks(range(len(kart_rgb[0]))) self.ax3.set_xticklabels(range(1, 1 + len(kart_rgb[0]))) self.ax3.set_yticks(range(len(kart_rgb))) self.ax3.set_yticklabels(range(1, 1 + len(kart_rgb))) self.ax3.axis('scaled') self.ax3.set_title('Herbivore distribution: ' + str(self.num_animals_per_species['Herbivore'])) self.ax4.imshow(self.animal_distribution_for_plot[:, :, 1], 'Reds', vmax=self.cmax_animals['Carnivore']) self.ax4.set_xticks(range(len(kart_rgb[0]))) self.ax4.set_xticklabels(range(1, 1 + len(kart_rgb[0]))) self.ax4.set_yticks(range(len(kart_rgb))) self.ax4.set_yticklabels(range(1, 1 + len(kart_rgb))) self.ax4.axis('scaled') self.ax4.set_title('Carnivore distribution: ' + str(self.num_animals_per_species['Carnivore'])) plt.pause(1e-9) def _save_graphics(self): """Saves graphics to file if file name given.""" if self._img_base is None: return plt.savefig('{base}_{num:05d}.{type}'.format(base=self._img_base, num=self._img_ctr, type=self._img_fmt)) self._img_ctr += 1 def make_movie(self): import glob img_array = [] for filename in glob.glob(self._img_base + '*' + self._img_fmt): img = cv2.imread(filename) height, width, layers = img.shape size = (width, height) img_array.append(img) out = cv2.VideoWriter('project.avi', cv2.VideoWriter_fourcc(*'DIVX'), 6, size) for i in range(len(img_array)): out.write(img_array[i]) out.release() @property def year(self): """Last year simulated.""" return self.tot_num_years @property def num_animals(self): """Total number of animals on island.""" return sum(self.island.num_animals()) @property def num_animals_per_species(self): """Number of animals per species in island, as dictionary.""" herb, carn = self.island.num_animals() return {'Herbivore': herb, 'Carnivore': carn} @property def animal_distribution_for_plot(self): """Pandas DataFrame with animal count per species for each cell on island.""" animal_list = np.zeros((self.island.rader, self.island.col, 2)) for i in range(self.island.rader): for j in range(self.island.col): if (i, j) in self.island.herbs.keys(): animal_list[i, j, 0] = len(self.island.herbs[(i, j)]) if (i, j) in self.island.carns.keys(): animal_list[i, j, 1] = len(self.island.carns[(i, j)]) return animal_list @property def animal_distribution(self): a = np.zeros((self.island.rader * self.island.col, 4)) for i in range(self.island.rader): a[i * self.island.col:(i + 1) * self.island.col, 0] = i c = np.arange(self.island.col) for i in range(self.island.rader): a[i * self.island.col:(i + 1) * self.island.col, 1] = c for pos in self.island.herbs.keys(): a[pos[0] * self.island.col + pos[1], 2] += len(self.island.herbs[pos]) for pos in self.island.carns.keys(): a[pos[0] * self.island.col + pos[1], 3] += len(self.island.carns[pos]) return pd.DataFrame(a, columns=['Row', 'Col', 'Herbivore', 'Carnivore'])