code: def plot_curve(log_dicts, args):
      if args.backend is not None:
          plt.switch_backend(args.backend)
      sns.set_style(args.style)
      # if legend is None, use {filename}_{key} as legend
      legend = args.legend
      if legend is None:
          legend = []
          for json_log in args.json_logs:
              for metric in args.keys:
                  legend.append(f"{json_log}_{metric}")
      assert len(legend) == (len(args.json_logs) * len(args.keys))
      metrics = args.keys
  
      # TODO: support dynamic eval interval(e.g. RTMDet) when plotting mAP.
      num_metrics = len(metrics)
      for i, log_dict in enumerate(log_dicts):
          epochs = list(log_dict.keys())
          for j, metric in enumerate(metrics):
              print(
                  f"plot curve of {args.json_logs[i]}, metric is {metric}"
              )
              if (
                  metric
                  not in log_dict[epochs[int(args.eval_interval) - 1]]
              ):
                  if "mAP" in metric:
                      raise KeyError(
                          f"{args.json_logs[i]} does not contain metric "
                          f'{metric}. Please check if "--no-validate" is '
                          "specified when you trained the model. Or check "
                          f"if the eval_interval {args.eval_interval} in args "
                          "is equal to the eval_interval during training."
                      )
                  raise KeyError(
                      f"{args.json_logs[i]} does not contain metric {metric}. "
                      "Please reduce the log interval in the config so that "
                      "interval is less than iterations of one epoch."
                  )
  
              if "mAP" in metric:
                  xs = []
                  ys = []
                  for epoch in epochs:
                      ys += log_dict[epoch][metric]
                      if log_dict[epoch][metric]:
                          xs += [epoch]
                  plt.xlabel("epoch")
                  plt.plot(
                      xs,
                      ys,
                      label=legend[i * num_metrics + j],
                      marker="o",
                  )
              else:
                  xs = []
                  ys = []
                  for epoch in epochs:
                      iters = log_dict[epoch]["step"]
                      xs.append(np.array(iters))
                      ys.append(
                          np.array(
                              log_dict[epoch][metric][: len(iters)]
                          )
                      )
                  xs = np.concatenate(xs)
                  ys = np.concatenate(ys)
                  plt.xlabel("iter")
                  plt.plot(
                      xs,
                      ys,
                      label=legend[i * num_metrics + j],
                      linewidth=0.5,
                  )
              plt.legend()
          if args.title is not None:
              plt.title(args.title)
      if args.out is None:
          plt.show()
      else:
          print(f"save curve to: {args.out}")
          plt.savefig(args.out)
          plt.cla()
  
file_path: mmdetection/tools/analysis_tools/analyze_logs.py
imports: import argparse
  import json
  from collections import defaultdict
  import matplotlib.pyplot
  import numpy
  import seaborn
label_desc: Use image node_id 2 for calling a global function with example usage: plot_curve(log_dicts, args) without return types