Skip to content

plot_annotation by labels, instead of optimally separating segments #57

Open
@janaab11

Description

@janaab11

The default implementation seems to separate overlapping segments into different lines (vertically), by parsing the start and end times of all segments, linearly from left to right. [source]

While this is pretty useful visually, there is another way to handle overlaps: plot differently-labelled segments on separate lines. In particular, this is useful if the different labels represent different audio environments and you want to visualize differences in your model's performance across environments/labels.

The actual implementation of this is pretty simple, and adds only three new lines of code:

  def plot_annotation(self, annotation: Annotation, ax=None, time=True, legend=True, separate_by="optimal"):

      if not self.crop:
          self.crop = annotation.get_timeline(copy=False).extent()

      cropped = annotation.crop(self.crop, mode='intersection')
      labels = cropped.labels()
      labels_dict = {label:i for i, label in enumerate(labels)}
      segments = [s for s, _ in cropped.itertracks()]

      ax = self.setup(ax=ax, time=time)

      for (segment, track, label), y in zip(
              cropped.itertracks(yield_label=True),
              self.get_y(segments)):
          if separate_by == "labels":
              y = 1. - 1. / (len(labels) + 1) * (1 + labels_dict.get(label))
          self.draw_segment(ax, segment, y, label=label)

Let me know if this works and i can make a PR!

An example of this implementation at work. The model clearly underperforms in the SYS label, by comparison:
human-vad
chonker-vad

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions