Scatter plot interactif : choisis deux features en X et Y. Clique sur un point pour écouter le son.
import os
import json
import pandas as pd
import plotly.graph_objects as go
import ipywidgets as widgets
from IPython.display import display, Audio
import warnings
warnings.filterwarnings('ignore')outputs_folder = "../outputs"
data = []
for sound_folder in os.listdir(outputs_folder):
json_path = os.path.join(outputs_folder, sound_folder, "results.json")
if os.path.exists(json_path):
with open(json_path, "r") as f:
result = json.load(f)
result["group"] = sound_folder[0]
data.append(result)
df = pd.DataFrame(data)
audio_dir = os.path.abspath("../data/sounds")
df["audio_path"] = df["file"].apply(lambda x: os.path.join(audio_dir, x))
print(f"✓ {len(df)} sons chargés")✓ 52 sons chargés
features = {
"F0 moyen (Hz)": "f0_mean",
"Variabilité F0": "f0_variability",
"Intensité (RMS)": "global_intensity",
"Centroïde spectral (Hz)": "spectral_centroid_mean",
"Largeur de bande (Hz)": "spectral_bandwidth_mean",
"Rolloff spectral (Hz)": "spectral_rolloff_mean",
"Durée (s)": "duration"
}
feature_selector = widgets.Dropdown(options=list(features.keys()),
description="Feature X",
style={"description_width": "initial"})
feature_selector2 = widgets.Dropdown(options=list(features.keys()),
value=list(features.keys())[1],
description="Feature Y",
style={"description_width": "initial"})
audio_out = widgets.Output()
fig_container = widgets.Output()
def update_plot(fx, fy):
with fig_container:
fig_container.clear_output(wait=True)
fig = go.FigureWidget()
for grp, color in [("A", "#1f77b4"), ("J", "#ff7f0e")]:
sub = df[df["group"] == grp]
fig.add_trace(go.Scatter(
x=sub[features[fx]], y=sub[features[fy]],
mode="markers", name=f"Groupe {grp}",
marker=dict(size=10, color=color, opacity=0.8),
text=sub["file"].values,
customdata=sub[["audio_path", "f0_mean", "f0_variability",
"global_intensity", "spectral_centroid_mean",
"spectral_bandwidth_mean", "duration"]].values,
hovertemplate=(
"<b>%{text}</b><br>"
"F0: %{customdata[1]:.1f} Hz<br>"
"Variabilité F0: %{customdata[2]:.2f}<br>"
"Intensité: %{customdata[3]:.5f}<br>"
"Centroïde: %{customdata[4]:.0f} Hz<br>"
"Largeur bande: %{customdata[5]:.0f} Hz<br>"
"Durée: %{customdata[6]:.2f} s<br>"
"<i>Cliquer pour écouter</i><extra></extra>"
)
))
fig.update_layout(title=f"{fx} vs {fy} — Cliquer pour écouter",
xaxis_title=fx, yaxis_title=fy)
def on_click(trace, points, state):
if points.point_inds:
idx = points.point_inds[0]
path = trace.customdata[idx][0]
name = trace.text[idx]
with audio_out:
audio_out.clear_output()
print(f"▶ {name}")
display(Audio(path, autoplay=True))
for trace in fig.data:
trace.on_click(on_click)
display(fig)
plot_out = widgets.interactive_output(
update_plot, {"fx": feature_selector, "fy": feature_selector2}
)
display(feature_selector, feature_selector2, fig_container, audio_out)
update_plot(feature_selector.value, feature_selector2.value)Loading...
Loading...
Loading...
Loading...