import marimo __generated_with = "0.13.0" app = marimo.App(width="full") @app.cell def _(): import marimo as mo import pandas as pd import plotly.graph_objects as go from sklearn.preprocessing import MinMaxScaler import matplotlib.cm as cm import matplotlib.colors as mcolors return cm, go, mcolors, mo, pd, MinMaxScaler @app.cell def _(MinMaxScaler, pd): # --- Load data df = pd.read_excel("plant_species_richness.xlsx") # Columns used in radar radar_cols = [ "Woody_Spps", "Veg_Spps", "Bryo_Spps", "Coffee structure index", "Coffee density in 30 x 30m plot", "Coffee dominance", ] # Normalize radar values scaler = MinMaxScaler() df_scaled = df.copy() df_scaled[radar_cols] = scaler.fit_transform(df[radar_cols]) site_options = df["Site ID"].tolist() return df, df_scaled, radar_cols, site_options @app.cell def _(mo, site_options): # --- Sidebar / UI controls mo.md("# Radar Chart – Site Comparison") return @app.cell def _(mo, site_options): selected_sites = mo.ui.multiselect( options=site_options, value=[site_options[0], site_options[1]], label="Select sites to compare", ) selected_sites return (selected_sites,) @app.cell def _(cm, df, df_scaled, go, mcolors, mo, radar_cols, selected_sites): # --- Colour logic (relative shading by yield) _cmap = cm.get_cmap("Blues", 256) def get_color(rank, total): norm = rank / max(total - 1, 1) return mcolors.to_hex(_cmap(0.3 + 0.7 * norm)) # --- Sort selected sites by yield selected_df = df[df["Site ID"].isin(selected_sites.value)].copy() selected_df = selected_df.sort_values("Mean_CC_Yield") n = len(selected_df) # --- Build radar figure fig = go.Figure() for i, (_, row) in enumerate(selected_df.iterrows()): site = row["Site ID"] yield_value = row["Mean_CC_Yield"] row_scaled = df_scaled[df_scaled["Site ID"] == site] values = row_scaled[radar_cols].values.flatten().tolist() values += values[:1] labels = radar_cols + [radar_cols[0]] color = get_color(i, n) fig.add_trace( go.Scatterpolar( r=values, theta=labels, fill="toself", name=f"{site} (Yield: {yield_value:.0f})", line=dict(color=color, width=3), opacity=0.85, hovertemplate=( "%{theta}
" "Normalized value: %{r:.2f}" ), ) ) fig.update_layout( polar=dict(radialaxis=dict(visible=True, range=[0, 1])), showlegend=True, height=700, ) mo.ui.plotly(fig)