class_docstr: This module plots histograms of all selected features for the last 'n' periods.
class_docstr_tok: ["This","module","plots","histograms","of","all","selected","features","for","the","last","'n","'","periods","."]
code: def transform(self, data_obj: dict, sections: list | None = None):
      if sections is None:
          sections = []
  
      features = self.get_features(list(data_obj.keys()))
      features_w_metrics = []
  
      # Treat these as static
      is_static_reference = self.reference_type in ["self", "external"]
  
      self.logger.info(f'Generating section "{self.section_name}".')
  
      for feature in tqdm(features, ncols=100):
          df = data_obj.get(feature, pd.DataFrame())
          last_n = (
              len(df.index)
              if (
                  len(df.index) < self.plot_hist_n
                  or self.plot_hist_n == 0
              )
              else self.plot_hist_n
          )
          hist_names = [
              hn for hn in self.hist_names if hn in df.columns
          ]
          if (
              len(hist_names) == 0
              and len(self.hist_name_starts_with) > 0
          ):
              # if no columns are given, find histogram columns.
              hist_names = [
                  c
                  for c in df.columns
                  if c.startswith(self.hist_name_starts_with)
              ]
          if len(hist_names) == 0:
              self.logger.debug(
                  f"for feature {feature} no histograms found. skipping."
              )
              continue
  
          # heatmap plot for each metric
          dates = [short_date(date) for date in df.index[:]]
          hists = [
              df[hist_names].iloc[-i].values
              for i in reversed(range(1, len(dates) + 1))
          ]
  
          # compute heatmaps
          heatmaps = _plot_heatmap(
              feature,
              dates,
              [h[0] for h in hists],
              self.top_n,
              self.cmap,
              self.hist_names,
              self.hist_names_formatted,
              self.descriptions,
          )
  
          # get base64 encoded plot for each metric; do parallel processing to speed up.
          dates = [short_date(date) for date in df.index[-last_n:]]
          hists = [
              df[hist_names].iloc[-i].values
              for i in reversed(range(1, last_n + 1))
          ]
  
          args = [
              (feature, dates[i], hists[i], hist_names, self.top_n)
              for i in range(last_n)
          ]
  
          # get histograms for each timestamp
          plots = parallel(_plot_histograms, args)
  
          plot_type_layouts = {}
  
          # filter out potential empty plots
          plots = [e for e in plots if len(e)]
          plots = sorted(plots, key=lambda plot: plot["date"])
  
          # basic checks for histograms
          histogram_basic_checks(plots)
  
          for plot in plots:
              for index in range(len(plot["hists"])):
                  if plot["hist_names"][index] == "histogram_prev1":
                      del plot["hist_names"][index]
                      del plot["hists"][index]
                      break
  
          # get histogram plots
          histogram = {}
          if len(plots) > 1:
              histogram = plot_histogram_overlay(
                  plots,
                  plots[0]["is_num"],
                  plots[0]["is_ts"],
                  is_static_reference,
                  top=self.top_n,
                  n_choices=self.n_choices,
              )
  
          if len(histogram) > 0:
              plot_type_layouts["histogram"] = histogram["layout"]
              histogram = [histogram]
          else:
              histogram = []
  
          # filter out potential empty heatmap plots, then prepend them to the sorted histograms
          hplots = [
              h
              for h in heatmaps
              if isinstance(h, dict) and len(h["plot"])
          ]
  
          if len(hplots) > 0:
              plot_type_layouts["heatmap"] = hplots[0]["layout"]
  
          plots = hplots + histogram
  
          features_w_metrics.append(
              {
                  "name": feature,
                  "plot_type_layouts": plot_type_layouts,
                  "plots": plots,
              }
          )
  
      sections.append(
          {
              "section_title": self.section_name,
              "section_description": self.description,
              "features": features_w_metrics,
          }
      )
      return sections
  
file_path: popmon/popmon/visualization/histogram_section.py
imports: from __future__ import annotations
  import numpy
  import pandas
  from histogrammar.util import get_hist_props
  from tqdm import tqdm
  from popmon.analysis.hist_numpy import assert_similar_hists, get_consistent_numpy_1dhists, get_consistent_numpy_entries
  from popmon.base import Module
  from popmon.config import HistogramSectionModel
  from popmon.utils import parallel, short_date
  from popmon.visualization.utils import histogram_basic_checks, plot_heatmap, plot_histogram_overlay
label_desc: Use image node_id 3 for calling the HistogramSection obj's underlying member method code with example usage: obj.transform(data_obj, sections) and returns: sections