code: def plot_histogram_overlay(
      plots=None,
      is_num: bool = True,
      is_ts: bool = False,
      is_static_reference: bool = True,
      top: int = 20,
      n_choices: int = 2,
  ):
      """Create and plot (overlapping/grouped) histogram(s) of column values.
  
      Copyright Eskapade:
      Kindly taken from Eskapade package and then modified. Reference link:
      https://github.com/KaveIO/Eskapade/blob/master/python/eskapade/visualization/vis_utils.py#L397
      License: https://github.com/KaveIO/Eskapade-Core/blob/master/LICENSE
      Modifications copyright INGA WB.
  
      :param list plots: list of dicts containing histograms for all timestamps
          :param bool is_num: True if observable to plot is numeric. default is True.
          :param bool is_ts: True if observable to plot is a timestamp. default is False.
      :param bool is_static_reference: True if the reference is static. default is True
      :param int top: only print the top 20 characters of x-labels and y-labels. default is 20.
      :param int n_choices: number of plots to compare at once
      :return: JSON encoded plot image
      :rtype: str
      """
  
      if plots is None:
          plots = []
      fig = go.Figure()
  
      alpha = 0.4
  
      # check the number of plots
      if len(plots) < 2:
          warnings.warn("insufficient plots for histogram inspection")
          return None
  
      base_plot = plots[0]
  
      # basic attribute check: time stamps treated as numeric.
      if is_ts:
          is_num = True
  
      # plot numeric and time stamps
      if is_num:
          # plot histogram
          for index in range(n_choices):
              bin_edges = plots[index]["hists"][0][1]
              bin_values = plots[index]["hists"][0][0]
              fig.add_trace(
                  go.Bar(
                      x=bin_edges[1:],
                      y=bin_values,
                      opacity=alpha,
                      showlegend=True,
                      name=plots[index]["date"],
                      meta=index,
                  )
              )
  
          # plot reference
          for index in range(1 if is_static_reference else n_choices):
              bin_edges = (
                  plots[index]["hists"][0][1]
                  if len(plots[index]["hists"]) < 2
                  else plots[index]["hists"][1][1]
              )
              bin_values = (
                  [0 for x in range(len(plots[index]["hists"][0][0]))]
                  if len(plots[index]["hists"]) < 2
                  else plots[index]["hists"][1][0]
              )
              fig.add_trace(
                  go.Bar(
                      x=bin_edges[1:],
                      y=bin_values,
                      opacity=alpha,
                      showlegend=True,
                      name=(
                          "no_ref"
                          if len(plots[index]["hists"]) < 2
                          else (
                              "Reference"
                              if is_static_reference
                              else (plots[index]["date"] + "-")
                              + plots[index]["hist_names"][1].split(
                                  "_"
                              )[-1]
                          )
                      ),
                      meta=index + 2,
                  )
              )
  
          # set x-axis properties
          xlim = [min(bin_edges), max(bin_edges)]
          fig.update_xaxes(range=xlim)
  
      # plot categories
      else:
          # plot histogram for first 'n_choices' timestamps
          for index in range(n_choices):
              labels = plots[index]["hists"][0][1]
              values = plots[index]["hists"][0][0]
              fig.add_trace(
                  go.Bar(
                      x=[xtick(lab, top) for lab in labels],
                      y=values,
                      opacity=alpha,
                      showlegend=True,
                      name=plots[index]["date"],
                      meta=index,
                  )
              )
  
          # plot reference for first 1 or 'n_choices' timestamps
          for index in range(1 if is_static_reference else n_choices):
              labels = (
                  plots[index]["hists"][0][1]
                  if len(plots[index]["hists"]) < 2
                  else plots[index]["hists"][1][1]
              )
              values = (
                  [0 for _ in range(len(plots[index]["hists"][0][0]))]
                  if len(plots[index]["hists"]) < 2
                  else plots[index]["hists"][1][0]
              )
              fig.add_trace(
                  go.Bar(
                      x=[xtick(lab, top) for lab in labels],
                      y=values,
                      opacity=alpha,
                      showlegend=True,
                      name=(
                          "no_ref"
                          if len(plots[index]["hists"]) < 2
                          else (
                              "Reference"
                              if is_static_reference
                              else plots[index]["date"]
                              + " "
                              + plots[index]["hist_names"][1].split(
                                  "_"
                              )[-1]
                          )
                      ),
                      meta=index + n_choices,
                  )
              )
  
      # set common histogram layout properties
      y_label = (
          str(base_plot["y_label"])
          if base_plot["y_label"] is not None
          else "Bin count"
      )
      fig.update_yaxes(
          title=y_label,
          minor_ticks="outside",
          showline=True,
          linecolor="black",
          mirror=True,
      )
      fig.update_xaxes(
          title=base_plot["feature"],
          minor_ticks="outside",
          showline=True,
          linecolor="black",
          mirror=True,
      )
      fig.update_layout(
          barmode="overlay",
          legend={
              "orientation": "h",
              "yanchor": "bottom",
              "y": 1.1,
              "xanchor": "left",
              "x": 0,
              "font": {"size": 10},
          },
          hovermode="x unified",
          margin={"l": 40, "r": 10},
      )
  
      # dropdown menu
      fig.update_layout(
          updatemenus=[
              *[
                  {
                      "buttons": [
                          {
                              "label": f'{plot["date"]}',
                              "method": "restyle",
                              "args": [
                                  {
                                      "y": [
                                          plot["hists"][0][0],
                                          (
                                              [
                                                  0
                                                  for _ in range(
                                                      len(
                                                          plot["hists"][
                                                              0
                                                          ][0]
                                                      )
                                                  )
                                              ]
                                              if len(plot["hists"]) < 2
                                              else plot["hists"][1][0]
                                          ),
                                      ],
                                      "name": [
                                          plot["date"],
                                          (
                                              "no_ref"
                                              if len(plot["hist_names"])
                                              < 2
                                              else (
                                                  "Reference"
                                                  if is_static_reference
                                                  else plots[index][
                                                      "date"
                                                  ]
                                                  + " "
                                                  + plot["hist_names"][
                                                      1
                                                  ].split("_")[-1]
                                              )
                                          ),
                                      ],
                                  },
                                  [b, b + 2],
                              ],
                          }
                          for plot in plots
                      ],
                      "active": b,
                      "pad": {"r": 10, "t": 10},
                      "borderwidth": 0,
                      "bgcolor": "#d3d3d3",
                      "showactive": True,
                      "x": b / 5,
                      "y": 1.45,
                      "xanchor": "left",
                      "yanchor": "top",
                  }
                  for b in range(n_choices)
              ],
              {
                  "buttons": [
                      {
                          "label": mode,
                          "method": "relayout",
                          "args": [
                              {
                                  "barmode": mode,
                              }
                          ],
                      }
                      for mode in ["overlay", "group"]
                  ],
                  "pad": {"r": 10, "t": 10},
                  "borderwidth": 0,
                  "bgcolor": "#d3d3d3",
                  "showactive": True,
                  "x": 1,
                  "y": 1.45,
                  "xanchor": "right",
                  "yanchor": "top",
              },
          ]
      )
  
      plot = json.loads(fig.to_json())
      return {
          "name": "Histogram Inspector ",
          "type": "histogram",
          "description": "",
          "plot": plot.get("data", ""),
          "layout": plot.get("layout", ""),
          "full_width": True,
      }
  
imports: from __future__ import annotations
  import datetime
  import json
  import logging
  import math
  import warnings
  from collections import defaultdict
  import numpy
  import pandas
  import plotly.express
  import plotly.graph_objects
  from popmon.resources import templates_env
label_desc: Use image node_id 10 for calling a global function with example usage: plot_histogram_overlay(plots, is_num, is_ts, is_static_reference, top, n_choices) and returns: dict, None