code: def plot_batch_prediction(batch, results_dict, cf, outfile=None):
      """
      plot the input images, ground truth annotations, and output predictions of a batch. If 3D batch, plots a 2D projection
      of one randomly sampled element (patient) in the batch. Since plotting all slices of patient volume blows up costs of
      time and space, only a section containing a randomly sampled ground truth annotation is plotted.
      :param batch: dict with keys: 'data' (input image), 'seg' (pixelwise annotations), 'pid'
      :param results_dict: list over batch element. Each element is a list of boxes (prediction and ground truth),
      where every box is a dictionary containing box_coords, box_score and box_type.
      """
      if outfile is None:
          outfile = os.path.join(
              cf.plot_dir, "pred_example_{}.png".format(cf.fold)
          )
  
      data = batch["data"]
      segs = batch["seg"]
      pids = batch["pid"]
      # for 3D, repeat pid over batch elements.
      if len(set(pids)) == 1:
          pids = [pids] * data.shape[0]
  
      seg_preds = results_dict["seg_preds"]
      roi_results = deepcopy(results_dict["boxes"])
  
      # Randomly sampled one patient of batch and project data into 2D slices for plotting.
      if cf.dim == 3:
          patient_ix = np.random.choice(data.shape[0])
          data = np.transpose(data[patient_ix], axes=(3, 0, 1, 2))
  
          # select interesting foreground section to plot.
          gt_boxes = [
              box["box_coords"]
              for box in roi_results[patient_ix]
              if box["box_type"] == "gt"
          ]
          if len(gt_boxes) > 0:
              z_cuts = [
                  np.max((int(gt_boxes[0][4]) - 5, 0)),
                  np.min((int(gt_boxes[0][5]) + 5, data.shape[0])),
              ]
          else:
              z_cuts = [
                  data.shape[0] // 2 - 5,
                  int(
                      data.shape[0] // 2
                      + np.min([10, data.shape[0] // 2])
                  ),
              ]
          p_roi_results = roi_results[patient_ix]
          roi_results = [[] for _ in range(data.shape[0])]
  
          # iterate over cubes and spread across slices.
          for box in p_roi_results:
              b = box["box_coords"]
              # dismiss negative anchor slices.
              slices = np.round(
                  np.unique(
                      np.clip(
                          np.arange(b[4], b[5] + 1),
                          0,
                          data.shape[0] - 1,
                      )
                  )
              )
              for s in slices:
                  roi_results[int(s)].append(box)
                  roi_results[int(s)][-1]["box_coords"] = b[:4]
  
          roi_results = roi_results[z_cuts[0] : z_cuts[1]]
          data = data[z_cuts[0] : z_cuts[1]]
          segs = np.transpose(segs[patient_ix], axes=(3, 0, 1, 2))[
              z_cuts[0] : z_cuts[1]
          ]
          seg_preds = np.transpose(
              seg_preds[patient_ix], axes=(3, 0, 1, 2)
          )[z_cuts[0] : z_cuts[1]]
          pids = [pids[patient_ix]] * data.shape[0]
  
      try:
          # all dimensions except for the 'channel-dimension' are required to match
          for i in [0, 2, 3]:
              assert (
                  data.shape[i] == segs.shape[i] == seg_preds.shape[i]
              )
      except:
          raise Warning(
              "Shapes of arrays to plot not in agreement!"
              "Shapes {} vs. {} vs {}".format(
                  data.shape, segs.shape, seg_preds.shape
              )
          )
  
      show_arrays = np.concatenate(
          [data, segs, seg_preds, data[:, 0][:, None]], axis=1
      ).astype(float)
      approx_figshape = (
          4 * show_arrays.shape[0],
          4 * show_arrays.shape[1],
      )
      fig = plt.figure(figsize=approx_figshape)
      gs = gridspec.GridSpec(
          show_arrays.shape[1] + 1, show_arrays.shape[0]
      )
      gs.update(wspace=0.1, hspace=0.1)
      for b in range(show_arrays.shape[0]):
          for m in range(show_arrays.shape[1]):
              ax = plt.subplot(gs[m, b])
              ax.axis("off")
              if m < show_arrays.shape[1]:
                  arr = show_arrays[b, m]
  
              if m < data.shape[1] or m == show_arrays.shape[1] - 1:
                  cmap = "gray"
                  vmin = None
                  vmax = None
              else:
                  cmap = None
                  vmin = 0
                  vmax = cf.num_seg_classes - 1
  
              if m == 0:
                  plt.title("{}".format(pids[b][:10]), fontsize=20)
  
              plt.imshow(arr, cmap=cmap, vmin=vmin, vmax=vmax)
              if m >= (data.shape[1]):
                  for box in roi_results[b]:
                      if (
                          box["box_type"] != "patient_tn_box"
                      ):  # don't plot true negative dummy boxes.
                          coords = box["box_coords"]
                          if box["box_type"] == "det":
                              # dont plot background preds or low confidence boxes.
                              if (
                                  box["box_pred_class_id"] > 0
                                  and box["box_score"] > 0.1
                              ):
                                  plot_text = True
                                  score = np.max(box["box_score"])
                                  score_text = "{}|{:.0f}".format(
                                      box["box_pred_class_id"],
                                      score * 100,
                                  )
                                  # if prob detection: plot only boxes from correct sampling instance.
                                  if (
                                      "sample_id" in box.keys()
                                      and int(box["sample_id"])
                                      != m - data.shape[1] - 2
                                  ):
                                      continue
                                  # if prob detection: plot reconstructed boxes only in corresponding line.
                                  if (
                                      not "sample_id" in box.keys()
                                      and m != data.shape[1] + 1
                                  ):
                                      continue
  
                                  score_font_size = 7
                                  text_color = "w"
                                  text_x = coords[1] + 10 * (
                                      box["box_pred_class_id"] - 1
                                  )  # avoid overlap of scores in plot.
                                  text_y = coords[2] + 5
                              else:
                                  continue
                          elif box["box_type"] == "gt":
                              plot_text = True
                              score_text = int(box["box_label"])
                              score_font_size = 7
                              text_color = "r"
                              text_x = coords[1]
                              text_y = coords[0] - 1
                          else:
                              plot_text = False
  
                          color_var = (
                              "extra_usage"
                              if "extra_usage" in list(box.keys())
                              else "box_type"
                          )
                          color = cf.box_color_palette[box[color_var]]
                          plt.plot(
                              [coords[1], coords[3]],
                              [coords[0], coords[0]],
                              color=color,
                              linewidth=1,
                              alpha=1,
                          )  # up
                          plt.plot(
                              [coords[1], coords[3]],
                              [coords[2], coords[2]],
                              color=color,
                              linewidth=1,
                              alpha=1,
                          )  # down
                          plt.plot(
                              [coords[1], coords[1]],
                              [coords[0], coords[2]],
                              color=color,
                              linewidth=1,
                              alpha=1,
                          )  # left
                          plt.plot(
                              [coords[3], coords[3]],
                              [coords[0], coords[2]],
                              color=color,
                              linewidth=1,
                              alpha=1,
                          )  # right
                          if plot_text:
                              plt.text(
                                  text_x,
                                  text_y,
                                  score_text,
                                  fontsize=score_font_size,
                                  color=text_color,
                              )
  
      try:
          plt.savefig(outfile)
      except:
          raise Warning("failed to save plot.")
      plt.close(fig)
  
file_path: medicaldetectiontoolkit/plotting.py
imports: import matplotlib
  import matplotlib.pyplot
  import matplotlib.gridspec
  import numpy
  import os
  from copy import deepcopy
label_desc: Use image node_id 1 for calling a global function with example usage: plot_batch_prediction(batch, results_dict, cf, outfile) without return types