duongthienz commited on
Commit
5775715
·
verified ·
1 Parent(s): e1cd247

update timespoken w multi

Browse files
Files changed (1) hide show
  1. utils.py +95 -39
utils.py CHANGED
@@ -333,7 +333,7 @@ def build_fig_pie1(df3, catTypeColors):
333
  """Voice category pie chart."""
334
  fig = go.Figure()
335
  fig.update_layout(
336
- title_text="Percentage of each Voice Category",
337
  colorway=catTypeColors,
338
  **TRANSPARENT_BG,
339
  )
@@ -348,7 +348,7 @@ def build_fig_pie2(df4, speakerNames, speaker_color_map, catColors, get_display_
348
  colors = [speaker_color_map.get(n, _SPEAKER_PALETTE[i % len(_SPEAKER_PALETTE)])
349
  for i, n in enumerate(df4["names"])]
350
  fig = go.Figure()
351
- fig.update_layout(title_text="Percentage of Speakers per Role", **TRANSPARENT_BG)
352
  fig.add_trace(go.Pie(values=df4["values"], labels=df4["names"],
353
  marker_colors=colors, sort=False))
354
  return fig
@@ -392,7 +392,7 @@ def build_fig_sunburst(df5, catTypeColors, speaker_color_map, get_display_name_f
392
  values="percentiles",
393
  custom_data=["labels", "valueStrings", "percentiles", "parentNames", "parentPercentiles"],
394
  color="labels",
395
- title="Percentage of each Voice Category with Speakers",
396
  color_discrete_map=color_map,
397
  )
398
  fig.update_traces(hovertemplate="<br>".join([
@@ -406,6 +406,84 @@ def build_fig_sunburst(df5, catTypeColors, speaker_color_map, get_display_name_f
406
  return fig
407
 
408
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  def build_fig_treemap(df5, catTypeColors, speaker_color_map, get_display_name_fn, currFile):
410
  """Treemap voice-category chart."""
411
  df5 = df5.copy()
@@ -421,7 +499,7 @@ def build_fig_treemap(df5, catTypeColors, speaker_color_map, get_display_name_fn
421
  values="percentiles",
422
  custom_data=["labels", "valueStrings", "percentiles", "parentNames", "parentPercentiles"],
423
  color="labels",
424
- title="Division of Speakers in each Voice Category",
425
  color_discrete_map=color_map,
426
  )
427
  fig.update_traces(hovertemplate="<br>".join([
@@ -455,7 +533,7 @@ def build_fig_timeline(speakers_dataFrame, currTotalTime, speaker_color_map, get
455
 
456
  fig = px.timeline(
457
  df, x_start="Start", x_end="Finish", y="Resource", color="Resource",
458
- title="Timeline of Audio with Speakers",
459
  color_discrete_map=speaker_color_map,
460
  )
461
  fig.update_yaxes(autorange="reversed")
@@ -506,63 +584,41 @@ def _darken_hex(hex_color, factor=0.55):
506
 
507
  def build_fig_bar(df2, speakerNames, catColors, speaker_color_map, get_display_name_fn, currFile, mv_per_speaker=None):
508
  """Horizontal bar chart — time spoken per speaker (hh:mm:ss.ss).
509
- Only individual speakers are shown; role/category rows are excluded.
510
  """
511
  mv_per_speaker = mv_per_speaker or {}
512
  df2 = df2.copy()
513
  df2 = df2[df2["names"].isin(speakerNames)]
514
 
515
- # Map raw speaker names to display names
516
- raw_to_display = {sp: get_display_name_fn(sp, currFile) for sp in df2["names"]}
517
- df2["display"] = df2["names"].map(raw_to_display)
518
- df2["mv_secs"] = df2["names"].map(lambda sp: mv_per_speaker.get(sp, 0.0))
519
- df2["sv_secs"] = (df2["values"] - df2["mv_secs"]).clip(lower=0)
520
  df2["time_label"] = df2["values"].apply(_seconds_to_hhmmss)
521
  df2["mv_time_label"] = df2["mv_secs"].apply(_seconds_to_hhmmss)
522
 
523
- # Build display-keyed color maps
524
  disp_color_map = {raw_to_display[sp]: speaker_color_map.get(raw_to_display[sp], "#aaaaaa")
525
  for sp in df2["names"]}
526
- disp_dark_map = {disp: _darken_hex(col) for disp, col in disp_color_map.items()}
527
 
528
  fig = go.Figure()
529
-
530
- # Trace 1: single-voice portion (base color)
531
  for _, row in df2.iterrows():
532
  col = disp_color_map.get(row["display"], "#aaaaaa")
533
  fig.add_trace(go.Bar(
534
- x=[row["sv_secs"]],
535
- y=[row["display"]],
536
- orientation="h",
537
- marker_color=col,
538
- showlegend=False,
539
  customdata=[[row["display"], row["time_label"], row["mv_time_label"]]],
540
- hovertemplate=(
541
- "<b>%{customdata[0]}</b><br>"
542
- "Total: %{customdata[1]}<br>"
543
- "Multi Voice: %{customdata[2]}"
544
- "<extra></extra>"
545
- ),
546
  ))
547
-
548
- # Trace 2: multi-voice portion (darker shade stacked on top)
549
  for _, row in df2.iterrows():
550
  if row["mv_secs"] <= 0:
551
  continue
552
  dark = disp_dark_map.get(row["display"], "#555555")
553
  fig.add_trace(go.Bar(
554
- x=[row["mv_secs"]],
555
- y=[row["display"]],
556
- orientation="h",
557
- marker_color=dark,
558
- showlegend=False,
559
  customdata=[[row["display"], row["time_label"], row["mv_time_label"]]],
560
- hovertemplate=(
561
- "<b>%{customdata[0]}</b><br>"
562
- "Total: %{customdata[1]}<br>"
563
- "Multi Voice: %{customdata[2]}"
564
- "<extra></extra>"
565
- ),
566
  ))
567
 
568
  fig.update_layout(
 
333
  """Voice category pie chart."""
334
  fig = go.Figure()
335
  fig.update_layout(
336
+ title_text="Percentage of each voice category",
337
  colorway=catTypeColors,
338
  **TRANSPARENT_BG,
339
  )
 
348
  colors = [speaker_color_map.get(n, _SPEAKER_PALETTE[i % len(_SPEAKER_PALETTE)])
349
  for i, n in enumerate(df4["names"])]
350
  fig = go.Figure()
351
+ fig.update_layout(title_text="Percentage of speakers per role", **TRANSPARENT_BG)
352
  fig.add_trace(go.Pie(values=df4["values"], labels=df4["names"],
353
  marker_colors=colors, sort=False))
354
  return fig
 
392
  values="percentiles",
393
  custom_data=["labels", "valueStrings", "percentiles", "parentNames", "parentPercentiles"],
394
  color="labels",
395
+ title="Percentage of each voice category with speakers (Combination)",
396
  color_discrete_map=color_map,
397
  )
398
  fig.update_traces(hovertemplate="<br>".join([
 
406
  return fig
407
 
408
 
409
+ def build_fig_sunburst_single(df5, speaker_color_map, get_display_name_fn, currFile):
410
+ """Sunburst showing only Single Voice speakers."""
411
+ df5 = df5.copy()
412
+ df5["labels"] = df5["labels"].apply(lambda s: get_display_name_fn(s, currFile))
413
+ df5["parentNames"] = df5["parentNames"].apply(lambda s: get_display_name_fn(s, currFile))
414
+
415
+ # Keep only the Single Voice parent row and its children
416
+ keep_ids = {"OV"} | {row["ids"] for _, row in df5.iterrows()
417
+ if row["parents"] == "OV"}
418
+ df5 = df5[df5["ids"].isin(keep_ids)].copy()
419
+ # Re-root: Single Voice becomes the top-level (parent = "")
420
+ df5.loc[df5["ids"] == "OV", "parents"] = ""
421
+
422
+ color_map = {lbl: speaker_color_map.get(lbl, _SPEAKER_PALETTE[i % len(_SPEAKER_PALETTE)])
423
+ for i, lbl in enumerate(df5["labels"])}
424
+ color_map["Single Voice"] = _PALETTE[0]
425
+
426
+ fig = px.sunburst(
427
+ df5,
428
+ branchvalues="total",
429
+ names="labels", ids="ids", parents="parents",
430
+ values="percentiles",
431
+ custom_data=["labels", "valueStrings", "percentiles", "parentNames", "parentPercentiles"],
432
+ color="labels",
433
+ title="Percentage of each voice category with speakers (Single Voice)",
434
+ color_discrete_map=color_map,
435
+ )
436
+ fig.update_traces(hovertemplate="<br>".join([
437
+ "<b>%{customdata[0]}</b>",
438
+ "Duration: %{customdata[1]}s",
439
+ "Percentage of Total: %{customdata[2]:.2f}%",
440
+ "Parent: %{customdata[3]}",
441
+ "Percentage of Parent: %{customdata[4]:.2f}%",
442
+ ]))
443
+ fig.update_layout(**TRANSPARENT_BG, font_color="#323236")
444
+ return fig
445
+
446
+
447
+ def build_fig_sunburst_multi(df5, speaker_color_map, get_display_name_fn, currFile):
448
+ """Sunburst showing only Multi Voice speakers."""
449
+ df5 = df5.copy()
450
+ df5["labels"] = df5["labels"].apply(lambda s: get_display_name_fn(s, currFile))
451
+ df5["parentNames"] = df5["parentNames"].apply(lambda s: get_display_name_fn(s, currFile))
452
+
453
+ # Keep only the Multi Voice parent row and its children
454
+ keep_ids = {"MV"} | {row["ids"] for _, row in df5.iterrows()
455
+ if row["parents"] == "MV"}
456
+ df5 = df5[df5["ids"].isin(keep_ids)].copy()
457
+ if df5.empty:
458
+ return None
459
+ # Re-root: Multi Voice becomes the top-level (parent = "")
460
+ df5.loc[df5["ids"] == "MV", "parents"] = ""
461
+
462
+ color_map = {lbl: speaker_color_map.get(lbl, _SPEAKER_PALETTE[i % len(_SPEAKER_PALETTE)])
463
+ for i, lbl in enumerate(df5["labels"])}
464
+ color_map["Multi Voice"] = _PALETTE[9]
465
+
466
+ fig = px.sunburst(
467
+ df5,
468
+ branchvalues="total",
469
+ names="labels", ids="ids", parents="parents",
470
+ values="percentiles",
471
+ custom_data=["labels", "valueStrings", "percentiles", "parentNames", "parentPercentiles"],
472
+ color="labels",
473
+ title="Percentage of each voice category with speakers (Multiple Voices)",
474
+ color_discrete_map=color_map,
475
+ )
476
+ fig.update_traces(hovertemplate="<br>".join([
477
+ "<b>%{customdata[0]}</b>",
478
+ "Duration: %{customdata[1]}s",
479
+ "Percentage of Total: %{customdata[2]:.2f}%",
480
+ "Parent: %{customdata[3]}",
481
+ "Percentage of Parent: %{customdata[4]:.2f}%",
482
+ ]))
483
+ fig.update_layout(**TRANSPARENT_BG, font_color="#323236")
484
+ return fig
485
+
486
+
487
  def build_fig_treemap(df5, catTypeColors, speaker_color_map, get_display_name_fn, currFile):
488
  """Treemap voice-category chart."""
489
  df5 = df5.copy()
 
499
  values="percentiles",
500
  custom_data=["labels", "valueStrings", "percentiles", "parentNames", "parentPercentiles"],
501
  color="labels",
502
+ title="Division of speakers in each voice category",
503
  color_discrete_map=color_map,
504
  )
505
  fig.update_traces(hovertemplate="<br>".join([
 
533
 
534
  fig = px.timeline(
535
  df, x_start="Start", x_end="Finish", y="Resource", color="Resource",
536
+ title="Timeline of audio with speakers",
537
  color_discrete_map=speaker_color_map,
538
  )
539
  fig.update_yaxes(autorange="reversed")
 
584
 
585
  def build_fig_bar(df2, speakerNames, catColors, speaker_color_map, get_display_name_fn, currFile, mv_per_speaker=None):
586
  """Horizontal bar chart — time spoken per speaker (hh:mm:ss.ss).
587
+ Each bar has a darker overlay showing the speaker's multi-voice portion.
588
  """
589
  mv_per_speaker = mv_per_speaker or {}
590
  df2 = df2.copy()
591
  df2 = df2[df2["names"].isin(speakerNames)]
592
 
593
+ raw_to_display = {sp: get_display_name_fn(sp, currFile) for sp in df2["names"]}
594
+ df2["display"] = df2["names"].map(raw_to_display)
595
+ df2["mv_secs"] = df2["names"].map(lambda sp: mv_per_speaker.get(sp, 0.0))
596
+ df2["sv_secs"] = (df2["values"] - df2["mv_secs"]).clip(lower=0)
 
597
  df2["time_label"] = df2["values"].apply(_seconds_to_hhmmss)
598
  df2["mv_time_label"] = df2["mv_secs"].apply(_seconds_to_hhmmss)
599
 
 
600
  disp_color_map = {raw_to_display[sp]: speaker_color_map.get(raw_to_display[sp], "#aaaaaa")
601
  for sp in df2["names"]}
602
+ disp_dark_map = {d: _darken_hex(c) for d, c in disp_color_map.items()}
603
 
604
  fig = go.Figure()
 
 
605
  for _, row in df2.iterrows():
606
  col = disp_color_map.get(row["display"], "#aaaaaa")
607
  fig.add_trace(go.Bar(
608
+ x=[row["sv_secs"]], y=[row["display"]], orientation="h",
609
+ marker_color=col, showlegend=False,
 
 
 
610
  customdata=[[row["display"], row["time_label"], row["mv_time_label"]]],
611
+ hovertemplate="<b>%{customdata[0]}</b><br>Total: %{customdata[1]}<br>Multi Voice: %{customdata[2]}<extra></extra>",
 
 
 
 
 
612
  ))
 
 
613
  for _, row in df2.iterrows():
614
  if row["mv_secs"] <= 0:
615
  continue
616
  dark = disp_dark_map.get(row["display"], "#555555")
617
  fig.add_trace(go.Bar(
618
+ x=[row["mv_secs"]], y=[row["display"]], orientation="h",
619
+ marker_color=dark, showlegend=False,
 
 
 
620
  customdata=[[row["display"], row["time_label"], row["mv_time_label"]]],
621
+ hovertemplate="<b>%{customdata[0]}</b><br>Total: %{customdata[1]}<br>Multi Voice: %{customdata[2]}<extra></extra>",
 
 
 
 
 
622
  ))
623
 
624
  fig.update_layout(