import pandas as pd
import numpy as np
import [Link] as plt
import seaborn as sn
from [Link] import files
[Link](context="notebook", style="whitegrid")
file_path = "ChecklistReptile_May2025.xlsx"
raw = pd.read_excel(file_path, sheet_name="Sheet1")
data = raw[['ganzh', 'Family', 'order']].dropna()
data['Family'] = data['Family'].astype(str).[Link]().[Link]()
data['order'] = data['order'].astype(str).[Link]().[Link]()
data['Genus'] = data['ganzh'].astype(str).[Link]().str[0]
data = data.drop_duplicates(subset=['ganzh', 'Family', 'order', 'Genus'])
[Link]()
def shannon_index(counts: [Link]) -> float:
counts = [Link](counts, dtype=float)
total = [Link]()
if total <= 0:
return 0.0
p = counts[counts > 0] / total
return float(-(p * [Link](p)).sum())
def simpson_gini(counts: [Link]) -> float:
counts = [Link](counts, dtype=float)
total = [Link]()
if total <= 0:
return 0.0
p = counts / total
return float(1.0 - [Link](p ** 2))
def chao1_richness(counts: [Link]) -> float:
#Estimator richness Chao1 berbasis "kelas" (di sini: GENUS),
#counts = jumlah spesies per genus
counts = [Link](counts, dtype=int)
counts = counts[counts > 0]
S_obs = len(counts)
F1 = int([Link](counts == 1)) # singleton
F2 = int([Link](counts == 2)) # doubleton
if S_obs == 0:
return 0.0
if F2 > 0:
return float(S_obs + (F1 ** 2) / (2.0 * F2))
#Jika tidak ada doubleton, pakai pendekatan bias-corrected sederhana
return float(S_obs + (F1 * (F1 - 1)) / 2.0)
order_family = [Link](['order','Family']).size().reset_index(name='count')
mat_order_family = order_family.pivot(index='order', columns='Family',
values='count').fillna(0).astype(int)
#Hitung indeks Antar Family di tiap Order
shannon_order = mat_order_family.apply(lambda row: shannon_index([Link]),
axis=1)
simpson_order = mat_order_family.apply(lambda row: simpson_gini([Link]),
axis=1)
div_order = [Link]({
'order': mat_order_family.index,
'shannon_family_div': shannon_order.values,
'simpson_family_div': simpson_order.values,
'richness_family': (mat_order_family > 0).sum(axis=1).values,
'total_species': mat_order_family.sum(axis=1).values
}).sort_values('shannon_family_div', ascending=False)
div_order.head()
family_genus = [Link](['Family','Genus']).size().reset_index(name='count')
mat_family_genus = family_genus.pivot(index='Family', columns='Genus',
values='count').fillna(0).astype(int)
#Hitung indeks Antar Genus dalam tiap Family
shannon_family = mat_family_genus.apply(lambda row: shannon_index([Link]),
axis=1)
simpson_family = mat_family_genus.apply(lambda row: simpson_gini([Link]),
axis=1)
chao1_family = mat_family_genus.apply(lambda row: chao1_richness([Link]),
axis=1)
div_family = [Link]({
'family': mat_family_genus.index,
'shannon_genus_div': shannon_family.values,
'simpson_genus_div': simpson_family.values,
'chao1_genus_richness': chao1_family.values,
'observed_genus': (mat_family_genus > 0).sum(axis=1).values,
'total_species_in_family': mat_family_genus.sum(axis=1).values
}).reset_index(drop=True)
diversity_df = div_family.copy() # <-- untuk konsistensi pemakaian berikutnya
diversity_df.head()
#Visualisasi Datanya
[Link](figsize=(10,6))
[Link](data=div_order, x='shannon_family_div', y='order', palette="viridis")
[Link]("Keragaman Family dalam Tiap Order (Shannon Index)")
[Link]("Shannon Index")
[Link]("Order")
[Link]()
top20 = div_family.nlargest(20, 'observed_genus')
[Link](figsize=(10,6))
[Link](top20['observed_genus'], top20['family'], label="Observed")
[Link](top20['chao1_genus_richness'], top20['family'], label="Chao1 Estimate",
marker="o", facecolors='none', edgecolors='red')
[Link]()
[Link]("Observed vs Chao1 Estimated Genus Richness (Top 20 Family)")
[Link]("Jumlah Genus")
[Link]("Family")
[Link]()
from [Link] import pearsonr, spearmanr
metrics = ['shannon_genus_div','simpson_genus_div','chao1_genus_richness']
df_corr = diversity_df[metrics].replace([[Link], -[Link]],
[Link]).dropna(how='any')
#Matriks korelasi
corr_pearson = df_corr.corr(method='pearson')
corr_spearman = df_corr.corr(method='spearman')
print("=== Pearson correlation ===")
display(corr_pearson.round(3))
print("\n=== Spearman correlation ===")
display(corr_spearman.round(3))
#Heatmap Pearson
[Link](figsize=(6,4))
[Link](corr_pearson, annot=True, fmt=".2f", cmap="coolwarm", vmin=-1, vmax=1,
linewidths=.5)
[Link]("Korelasi (Pearson) antar Indeks: Shannon, Simpson, Chao1")
[Link]()
#Heatmap Spearman
[Link](figsize=(6,4))
[Link](corr_spearman, annot=True, fmt=".2f", cmap="coolwarm", vmin=-1, vmax=1,
linewidths=.5)
[Link]("Korelasi (Spearman) antar Indeks: Shannon, Simpson, Chao1")
[Link]()
#Pairwise scatter + garis regresi + anotasi r & p (Pearson)
from [Link] import PairGrid
def annotate_corr(x, y, **kws):
r, p = pearsonr(x, y)
ax = [Link]()
[Link](0.05, 0.9, f"r = {r:.2f}\np = {p:.3g}", transform=[Link],
fontsize=9,
bbox=dict(boxstyle="round", facecolor="white", alpha=0.6))
g = PairGrid(df_corr[metrics], diag_sharey=False)
g.map_lower([Link], s=20, alpha=0.7)
g.map_upper([Link], scatter_kws={'s':20, 'alpha':0.6},
line_kws={'linewidth':1})
g.map_upper(annotate_corr)
g.map_diag([Link], fill=True)
[Link]("Hubungan Antar Indeks Biodiversitas (Pearson)", y=1.02)
[Link]()
import [Link] as sm
def residualize(y, X):
Xc = sm.add_constant(X)
model = [Link](y, Xc).fit()
return y - [Link](Xc)
#Residualkan setiap indeks terhadap total_species_in_family (log transform)
Xsize = np.log1p(diversity_df['total_species_in_family'].values)
res_shannon = residualize(diversity_df['shannon_genus_div'].values, Xsize)
res_simpson = residualize(diversity_df['simpson_genus_div'].values, Xsize)
res_chao1 = residualize(diversity_df['chao1_genus_richness'].values, Xsize)
res_df = [Link]({'Shannon_res': res_shannon,
'Simpson_res': res_simpson,
'Chao1_res': res_chao1})
corr_resid = res_df.corr(method='pearson')
print("=== Pearson correlation on residuals (kontrol ukuran) ===")
display(corr_resid.round(3))
[Link](figsize=(6,4))
[Link](corr_resid, annot=True, fmt=".2f", cmap="coolwarm", vmin=-1, vmax=1,
linewidths=.5)
[Link]("Korelasi (Pearson) antar Residual Indeks (kontrol ukuran family)")
[Link]()