class_docstr: Selects the right wrapper (based on the environment), runs, and saves the src.
code: def _plot_trajectory(self) -> None:
      import seaborn as sns
  
      sns.set_style("whitegrid")
      sns.set_palette("colorblind")
  
      d = self._data[self._computer]
  
      for sort_by in ["trials", "walltime"]:
          len_tasks = len(d.keys())
  
          traj = f"trajectory_{sort_by}"
          filename = Path(f"report/{traj}.png")
  
          # Collect data
          df = []
          for task in TASKS:
              objective = d[task.id]["objective"]
  
              for version, seeds in d[task.id][traj].items():
                  for seed, (X, Y) in seeds.items():
                      X = np.array(X)
                      Y = np.array(Y)
                      df.append(
                          pd.DataFrame(
                              {
                                  "task": task.name,
                                  "objective": objective,
                                  "version": [version] * len(X),
                                  "seed": [seed] * len(Y),
                                  "x": X,
                                  "y": Y,
                              }
                          )
                      )
                      # assert np.all(X[1:] > X[:-1]), f"X not strictly monotonically increasing, {version, seed, X, Y}"
                      # assert np.all(Y[1:] < Y[:-1]), f"Y not strictly monotonically decreasing, {version, seed, X, Y}"
          plot_df = pd.concat(df).reset_index(drop=True)
  
          # Plot
          plt.figure(rows=len_tasks)
          plt.tight_layout()
          plt.subplots_adjust(wspace=0.6)
  
          hue_order = list(plot_df["version"].unique())
  
          i = 0
          for task in TASKS:
              objective = d[task.id]["objective"]
  
              plt.subplot(len_tasks, 1, i + 1)
              plt.title(task.name)
  
              df = plot_df[plot_df["task"] == task.name]
  
              # Fill missing values
              x_unique = df["x"].unique()
              new_df = []
              for gid, gdf in df.groupby(by=["version", "seed"]):
                  x_missing = list(
                      set(x_unique).difference(set(gdf["x"].unique()))
                  )
                  gdf = pd.concat(
                      (
                          gdf,
                          pd.DataFrame(
                              {
                                  "version": gid[0],
                                  "seed": gid[1],
                                  "x": x_missing,
                                  "y": [np.nan] * len(x_missing),
                              }
                          ),
                      )
                  )
                  gdf.sort_values(by="x", inplace=True)
                  gdf.ffill(inplace=True)  # forward fill
                  new_df.append(gdf)
              df = pd.concat(new_df).reset_index(drop=True)
  
              ax = sns.lineplot(
                  data=df,
                  x="x",
                  y="y",
                  hue="version",
                  style=None,
                  lw=1,
                  hue_order=hue_order,
              )
              ax.legend()
              # ax.get_legend().remove()
  
              # plt.legend()
              ax.set_ylabel(objective)
  
              if task.y_log_scale:
                  ax.set_yscale("log")
  
              if task.x_log_scale:
                  ax.set_xscale("log")
  
              if i == len_tasks - 1:
                  ax.set_xlabel(sort_by)
  
              i += 1
  
          plt.save_figure(str(filename))
  
imports: from __future__ import annotations
  import sys
  import logging
  from typing import Any
  import numpy
  import json
  import socket
  from collections import defaultdict
  from pathlib import Path
  import pandas
  from src.tasks import TASKS
  from src.utils.exceptions import NotSupportedError
  from src.utils.styled_plot import plt
  from src.wrappers.v14 import Version14
  from src.wrappers.v20 import Version20
  from src.wrappers.wrapper import Wrapper
label_desc: Use image node_id 7 for calling the Benchmark obj's underlying member method code with example usage: obj._plot_trajectory() without return types