code: def histogram(self, tag, values, bins, step=None):
      
      if step is None:
        step = self._step
      else:
        self._step = step
      values = onp.array(values)
      bins = onp.array(bins)
      values = onp.reshape(values, -1)
      counts, limits = onp.histogram(values, bins=bins)
      # boundary logic
      cum_counts = onp.cumsum(onp.greater(counts, 0, dtype=onp.int32))
      start, end = onp.searchsorted(
          cum_counts, [0, cum_counts[-1] - 1], side='right')
      start, end = int(start), int(end) + 1
      counts = (
          counts[start -
                 1:end] if start > 0 else onp.concatenate([[0], counts[:end]]))
      limits = limits[start:end + 1]
      sum_sq = values.dot(values)
      histo = HistogramProto(
          min=values.min(),
          max=values.max(),
          num=len(values),
          sum=values.sum(),
          sum_squares=sum_sq,
          bucket_limit=limits.tolist(),
          bucket=counts.tolist())
      summary = Summary(value=[Summary.Value(tag=tag, histo=histo)])
      self.add_summary(summary, step)
docs: Saves histogram of values.
  
      Args:
        tag: str: label for this data
        values: ndarray: will be flattened by this routine
        bins: number of bins in histogram, or array of bins for onp.histogram
        step: int: training step