class_docstr: A callback that stores plots of the training and macro-averaged validation loss curve every n epochs.
  
  Args:
      every_n_epochs: Specifies how often the plots are generated.
          Setting this to a large value can save time since plotting can be time consuming
          (especially when small datasets are used).
class_docstr_tok: ["A","callback","that","stores","plots","of","the","training","and","macro-averaged","validation","loss","curve","every","n","epochs",".","Args",":","every_n_epochs",":","Specifies","how","often","the","plots","are","generated",".","Setting","this","to","a","large","value","can","save","time","since","plotting","can","be","time","consuming","(","especially","when","small","datasets","are","used",")","."]
code: def plot_loss(
      self, trainer: Trainer, pl_module: MetaLightningModule
  ) -> None:
      train_loss, train_steps = get_loss_steps("train_loss", trainer)
      val_loss_macro, val_steps = get_loss_steps(
          "val_loss_macro", trainer
      )
  
      fig, ax = plt.subplots()
      ax.semilogy(
          train_steps, train_loss, label="train_loss", alpha=0.5
      )
      ax.semilogy(
          val_steps, val_loss_macro, label="val_loss_macro", alpha=0.5
      )
      ax2 = ax.twinx()
      ax2.set_ylabel("crps scores", color="red")
      if pl_module.val_crps_scaled_macro:
          val_crps_scaled_macro, _ = get_loss_steps(
              "val_crps_scaled_macro", trainer
          )
          ax2.semilogy(
              val_steps,
              val_crps_scaled_macro,
              "r--",
              label="val_crps_scaled_macro",
          )
      else:
          val_crps_macro, _ = get_loss_steps("val_crps_macro", trainer)
          ax2.semilogy(
              val_steps, val_crps_macro, "r--", label="val_crps_macro"
          )
      ax2.legend(loc="upper right")
  
      ticks = range(0, trainer.current_epoch + 1, self.every_n_epochs)
      labels = [str(t) for t in ticks]
      ax.set_xticks(ticks)
      ax.set_xticklabels(labels, rotation=45)
      ax.legend(loc="upper left")
  
      fig.savefig(
          get_save_dir_from_csvlogger(trainer.logger) / f"loss.png",
          bbox_inches="tight",
      )
      plt.close(fig)
  
imports: from typing import Optional, Union, List
  from pytorch_lightning import Callback, Trainer
  import matplotlib.pyplot
  from meta.data.batch import TripletBatch
  from meta.models.module import MetaLightningModule
  from .common import get_save_dir_from_csvlogger, get_loss_steps
  from meta.data.batch import SeriesBatch
  from meta.vis.forecast import plot_quantile_forecast, plot_forecast_supportset_attention
label_desc: Use image node_id 4 for calling the LossPlotLoggerCallback obj's underlying member method code with example usage: obj.plot_loss(trainer, pl_module) without return types