Skip to content

Commit db82b6c

Browse files
committed
Implemented beta diversity
1 parent 6cfe755 commit db82b6c

7 files changed

+84
-29
lines changed

docs/source/overview.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,12 @@ The Gini-Simpson index is simply the complement of the Simpson index, that is it
5454

5555
```{math}
5656
G = 1 - \sum_{i = 1}^{K} p^2_i = 1 - S.
57-
```
57+
```
58+
59+
#### {math}`\beta`-diversity
60+
{math}`\beta`-diversity is a ratio between diersity over the whole metapopulation and the diversity per subpopulation. We implemented the diversity index suggested by Whittaker (1960; see also Wilson and Shmida, 1984):
61+
62+
```{math}
63+
\beta_W = \frac{K_m}{\bar{K}_s} - 1
64+
```
65+
where {math}`K_m` is the number of sets of traits in the whole metapopulation, and {math}`\bar{K}_s` is the average number of sets of traits in each subpopulation.

exploration.ipynb

+13-6
Large diffs are not rendered by default.

metapypulation/metapopulation.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def metapopulation_shannon_diversity(self) -> float:
214214
return shannon_diversity_index
215215

216216

217-
def metapopulation_test_sets(self) -> int:
217+
def metapopulation_count_sets(self) -> int:
218218
"""Calculates number of unique sets of traits in the whole metapopulation.
219219
220220
Returns:
@@ -278,6 +278,23 @@ def metapopulation_gini_diversity(self) -> float:
278278

279279
return gini_diversity_index
280280

281+
282+
def whittaker_beta_diversity(self) -> float:
283+
"""
284+
Calculate beta diversity as described by Whittaker (1960).
285+
286+
Returns:
287+
float: Whittaker beta diversity.
288+
"""
289+
metapopulation_sets_number = self.metapopulation_count_sets()
290+
subpopulation_set_counts = []
291+
for subpopulation in self.subpopulations:
292+
subpopulation_set_counts.append(subpopulation.count_traits_sets())
293+
294+
beta_diversity = metapopulation_sets_number / np.mean(subpopulation_set_counts) - 1
295+
296+
return beta_diversity
297+
281298

282299
def count_origin_id_spread(self) -> np.ndarray:
283300
"""

metapypulation/simulation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def run_single_replicate(self, replicate_id: int) -> None:
145145
shannon.append(np.mean(metapopulation.shannon_diversity_per_subpopulation()))
146146
simpson.append(np.mean(metapopulation.simpson_diversity_per_subpopulation()))
147147
gini.append(np.mean(metapopulation.gini_diversity_per_subpopulation()))
148-
metapop_counts.append(metapopulation.metapopulation_test_sets())
148+
metapop_counts.append(metapopulation.metapopulation_count_sets())
149149
metapop_shannon.append(metapopulation.metapopulation_shannon_diversity())
150150
metapop_simpson.append(metapopulation.metapopulation_simpson_diversity())
151151
metapop_gini.append(metapopulation.metapopulation_gini_diversity())

plotting.py

+26-9
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def plot_comparison_gini(dataset_1, dataset_2, title, legend_1, legend_2, output
5555
plt.savefig(output_file)
5656

5757

58-
def metapopulation_plot_comparison(dataset_1, dataset_2, title, legend_1, legend_2, output_file, what_measure, dataset_3 = None, legend_3 = None):
58+
def metapopulation_plot_comparison(dataset_1, dataset_2, title, legend_1, legend_2, output_file, what_measure, number_of_pulses = 5, length_of_pulses = 1, settling_period = 99, dataset_3 = None, legend_3 = None):
5959
if what_measure == 'set_counts':
6060
dataset_1_global = pd.read_csv(f"{dataset_1}_metapop_set_counts.csv", index_col=0)
6161
dataset_2_global = pd.read_csv(f"{dataset_2}_metapop_set_counts.csv", index_col=0)
@@ -68,30 +68,47 @@ def metapopulation_plot_comparison(dataset_1, dataset_2, title, legend_1, legend
6868
elif what_measure == 'gini':
6969
dataset_1_global = pd.read_csv(f"{dataset_1}_metapop_gini.csv", index_col=0)
7070
dataset_2_global = pd.read_csv(f"{dataset_2}_metapop_gini.csv", index_col=0)
71+
elif what_measure == 'beta':
72+
dataset_1_global = pd.read_csv(f"{dataset_1}_beta_diversity.csv", index_col=0)
73+
dataset_2_global = pd.read_csv(f"{dataset_2}_beta_diversity.csv", index_col=0)
7174
else:
7275
print("You need to decide what measure you will plot: 'set_counts', 'shannon', 'simpson' or 'gini'?")
7376

74-
plt.plot(dataset_1_global.mean(axis=1), color = 'xkcd:blue')
75-
plt.plot(dataset_2_global.mean(axis=1), color = 'xkcd:puce')
77+
line1, = plt.plot(dataset_1_global.mean(axis=1), color = 'xkcd:blue', label=f"{legend_1}")
78+
line2, = plt.plot(dataset_2_global.mean(axis=1), color = 'xkcd:puce', label=f"{legend_2}")
7679

7780
plt.fill_between(dataset_1_global.index, dataset_1_global.mean(axis=1) - dataset_1_global.std(axis=1), dataset_1_global.mean(axis=1) + dataset_1_global.std(axis=1), color='xkcd:blue', alpha=0.3)
7881
plt.fill_between(dataset_2_global.index, dataset_2_global.mean(axis=1) - dataset_2_global.std(axis=1), dataset_2_global.mean(axis=1) + dataset_2_global.std(axis=1), color='xkcd:puce', alpha=0.3)
7982

8083
plt.axvline(500, color="black", linestyle='--', ymax=1)
8184

8285
if dataset_3 is not None:
83-
# TODO FIX HERE
84-
dataset_3_global = pd.read_csv(f"{dataset_3}_metapop_set_counts.csv", index_col=0)
85-
plt.plot(dataset_3_global.mean(axis=1), color = 'xkcd:light purple')
86+
if what_measure == 'set_counts':
87+
dataset_3_global = pd.read_csv(f"{dataset_3}_metapop_set_counts.csv", index_col=0)
88+
elif what_measure == 'shannon':
89+
dataset_3_global == pd.read_csv(f"{dataset_3}_metapop_shannon.csv", index_col=0)
90+
elif what_measure == 'simpson':
91+
dataset_3_global = pd.read_csv(f"{dataset_3}_metapop_simpson.csv", index_col=0)
92+
elif what_measure == 'gini':
93+
dataset_3_global = pd.read_csv(f"{dataset_3}_metapop_gini.csv", index_col=0)
94+
elif what_measure == 'beta':
95+
dataset_3_global = pd.read_csv(f"{dataset_3}_beta_diversity.csv", index_col=0)
96+
else:
97+
print("You need to decide what measure you will plot: 'set_counts', 'shannon', 'simpson' or 'gini'?")
98+
99+
line3, = plt.plot(dataset_3_global.mean(axis=1), color = 'xkcd:light purple', label=f"{legend_3}")
86100
plt.fill_between(dataset_3_global.index, dataset_3_global.mean(axis=1) - dataset_3_global.std(axis=1), dataset_3_global.mean(axis=1) + dataset_3_global.std(axis=1), color='xkcd:light purple', alpha=0.3)
87101

88-
89102
if dataset_3 is not None:
90-
plt.legend([f"{legend_1}", f"{legend_2}", f"{legend_3}"])
103+
plt.legend(loc=3, handles=[line1, line2, line3])
91104
else:
92105
plt.legend([f"{legend_1}", f"{legend_2}"])
93106

94-
plt.ylabel("Number of feature sets")
107+
plt.axvline(500, color="black", linestyle='--', ymax=1)
108+
for i in range(1, number_of_pulses + 1):
109+
plt.axvline(500 + i*(length_of_pulses + settling_period), color="dimgrey", linestyle='--', ymax=1)
110+
111+
plt.ylabel(r"Whittaker $\beta$ Diversity")
95112
plt.xlabel("Generations (x100)")
96113
plt.grid(linestyle=':', linewidth=0.5)
97114
plt.title(title)

script_Kiel2025_diversity.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
measure_timing = 100
1111

1212
total_population = 800
13-
replicates = 10
13+
replicates = 50
1414
save_output = True
1515
interactions = ['neutral_interaction'] # 'axelrod_interaction'
1616
number_of_subpopulations = 8
@@ -26,7 +26,7 @@
2626

2727
count = 0
2828

29-
title = "singleConnection"
29+
title = "frontConnection"
3030
migration_config = np.genfromtxt(f"./configs/maritime_configs/{title}.csv", delimiter=",")
3131

3232
for interaction in interactions:
@@ -36,6 +36,7 @@
3636
subpop_gini_df = pd.DataFrame()
3737
metapop_set_counts_df = pd.DataFrame()
3838
metapop_gini_df = pd.DataFrame()
39+
beta_diversity_df = pd.DataFrame()
3940

4041
carrying_capacity = int(np.ceil(total_population / number_of_subpopulations)) # [283, 39, 39, 39]#
4142

@@ -53,6 +54,7 @@
5354
gini = []
5455
metapop_counts = []
5556
metapop_gini = []
57+
beta_diversity = []
5658

5759
t = 0
5860
for gen in range(burn_in):
@@ -67,8 +69,9 @@
6769
if t%measure_timing == 0:
6870
set_counts.append(np.mean(metapopulation.traits_sets_per_subpopulation()))
6971
gini.append(np.mean(metapopulation.gini_diversity_per_subpopulation()))
70-
metapop_counts.append(metapopulation.metapopulation_test_sets())
72+
metapop_counts.append(metapopulation.metapopulation_count_sets())
7173
metapop_gini.append(metapopulation.metapopulation_gini_diversity())
74+
beta_diversity.append(metapopulation.whittaker_beta_diversity())
7275

7376
t += 1
7477

@@ -95,15 +98,17 @@
9598
if t%measure_timing == 0:
9699
set_counts.append(np.mean(metapopulation.traits_sets_per_subpopulation()))
97100
gini.append(np.mean(metapopulation.gini_diversity_per_subpopulation()))
98-
metapop_counts.append(metapopulation.metapopulation_test_sets())
101+
metapop_counts.append(metapopulation.metapopulation_count_sets())
99102
metapop_gini.append(metapopulation.metapopulation_gini_diversity())
103+
beta_diversity.append(metapopulation.whittaker_beta_diversity())
100104

101105
t += 1
102106

103107
subpop_set_counts_df = pd.concat([subpop_set_counts_df, pd.Series(set_counts, name=replicate_id)], axis=1)
104108
subpop_gini_df = pd.concat([subpop_gini_df, pd.Series(gini, name=replicate_id)], axis=1)
105109
metapop_set_counts_df = pd.concat([metapop_set_counts_df, pd.Series(metapop_counts, name=replicate_id)], axis=1)
106110
metapop_gini_df = pd.concat([metapop_gini_df, pd.Series(metapop_gini, name=replicate_id)], axis=1)
111+
beta_diversity_df = pd.concat([beta_diversity_df, pd.Series(beta_diversity, name=replicate_id)], axis=1)
107112

108113
if verbose:
109114
print(f"Generation reached: {t}")
@@ -116,10 +121,11 @@
116121
# print(metapopulation.count_origin_id_spread())
117122

118123
if save_output:
119-
subpop_set_counts_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_subpop_set_counts.csv", sep=",")
120-
subpop_gini_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_subpop_gini.csv", sep=",")
121-
metapop_set_counts_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_metapop_set_counts.csv", sep=",")
122-
metapop_gini_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_metapop_gini.csv", sep=",")
124+
# subpop_set_counts_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_subpop_set_counts.csv", sep=",")
125+
# subpop_gini_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_subpop_gini.csv", sep=",")
126+
# metapop_set_counts_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_metapop_set_counts.csv", sep=",")
127+
# metapop_gini_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_metapop_gini.csv", sep=",")
128+
beta_diversity_df.to_csv(f"./Outputs/Kiel2025/{title}/{interaction}_{rate_of_migration}_{number_of_pulses}pulses_{pulse_length}gen_beta_diversity.csv", sep=",")
123129

124130
# subpop_gini_df.to_csv("test.csv")
125131

simulate_new_mutation.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
counts_pop_6.append(metapop.subpopulations[5].count_traits_sets())
6666
counts_pop_7.append(metapop.subpopulations[6].count_traits_sets())
6767
counts_pop_8.append(metapop.subpopulations[7].count_traits_sets())
68-
counts_metapop.append(metapop.metapopulation_test_sets())
68+
counts_metapop.append(metapop.metapopulation_count_sets())
6969
subpops_with_mutation.append(0)
7070
# if t%50000 == 0:
7171
# print(f"Gen {t}!")
@@ -86,7 +86,7 @@
8686
counts_pop_6.append(metapop.subpopulations[5].count_traits_sets())
8787
counts_pop_7.append(metapop.subpopulations[6].count_traits_sets())
8888
counts_pop_8.append(metapop.subpopulations[7].count_traits_sets())
89-
counts_metapop.append(metapop.metapopulation_test_sets())
89+
counts_metapop.append(metapop.metapopulation_count_sets())
9090
subpops_with_mutation.append(0)
9191
# if t%50000 == 0:
9292
# print(f"Gen {t}!")
@@ -119,7 +119,7 @@
119119
counts_pop_6.append(metapop.subpopulations[5].count_traits_sets())
120120
counts_pop_7.append(metapop.subpopulations[6].count_traits_sets())
121121
counts_pop_8.append(metapop.subpopulations[7].count_traits_sets())
122-
counts_metapop.append(metapop.metapopulation_test_sets())
122+
counts_metapop.append(metapop.metapopulation_count_sets())
123123

124124
feature_tests = []
125125
for subpop in metapop.subpopulations:

0 commit comments

Comments
 (0)