code: def histogram(name, data, step=None, buckets=None, description=None):
      """Write a histogram summary.
  
      See also `tf.summary.scalar`, `tf.summary.SummaryWriter`.
  
      Writes a histogram to the current default summary writer, for later analysis
      in TensorBoard's 'Histograms' and 'Distributions' dashboards (data written
      using this API will appear in both places). Like `tf.summary.scalar` points,
      each histogram is associated with a `step` and a `name`. All the histograms
      with the same `name` constitute a time series of histograms.
  
      The histogram is calculated over all the elements of the given `Tensor`
      without regard to its shape or rank.
  
      This example writes 2 histograms:
  
      ```python
      w = tf.summary.create_file_writer('test/logs')
      with w.as_default():
          tf.summary.histogram("activations", tf.random.uniform([100, 50]), step=0)
          tf.summary.histogram("initial_weights", tf.random.normal([1000]), step=0)
      ```
  
      A common use case is to examine the changing activation patterns (or lack
      thereof) at specific layers in a neural network, over time.
  
      ```python
      w = tf.summary.create_file_writer('test/logs')
      with w.as_default():
      for step in range(100):
          # Generate fake "activations".
          activations = [
              tf.random.normal([1000], mean=step, stddev=1),
              tf.random.normal([1000], mean=step, stddev=10),
              tf.random.normal([1000], mean=step, stddev=100),
          ]
  
          tf.summary.histogram("layer1/activate", activations[0], step=step)
          tf.summary.histogram("layer2/activate", activations[1], step=step)
          tf.summary.histogram("layer3/activate", activations[2], step=step)
      ```
  
      Arguments:
        name: A name for this summary. The summary tag used for TensorBoard will
          be this name prefixed by any active name scopes.
        data: A `Tensor` of any shape. The histogram is computed over its elements,
          which must be castable to `float64`.
        step: Explicit `int64`-castable monotonic step value for this summary. If
          omitted, this defaults to `tf.summary.experimental.get_step()`, which must
          not be None.
        buckets: Optional positive `int`. The output will have this
          many buckets, except in two edge cases. If there is no data, then
          there are no buckets. If there is data but all points have the
          same value, then all buckets' left and right endpoints are the same
          and only the last bucket has nonzero count. Defaults to 30 if not
          specified.
        description: Optional long-form description for this summary, as a
          constant `str`. Markdown is supported. Defaults to empty.
  
      Returns:
        True on success, or false if no summary was emitted because no default
        summary writer was available.
  
      Raises:
        ValueError: if a default writer exists, but no step was provided and
          `tf.summary.experimental.get_step()` is None.
      """
      # Avoid building unused gradient graphs for conds below. This works around
      # an error building second-order gradient graphs when XlaDynamicUpdateSlice
      # is used, and will generally speed up graph building slightly.
      data = tf.stop_gradient(data)
      summary_metadata = metadata.create_summary_metadata(
          display_name=None, description=description
      )
      # TODO(https://github.com/tensorflow/tensorboard/issues/2109): remove fallback
      summary_scope = (
          getattr(tf.summary.experimental, "summary_scope", None)
          or tf.summary.summary_scope
      )
  
      # TODO(ytjing): add special case handling.
      with summary_scope(
          name, "histogram_summary", values=[data, buckets, step]
      ) as (tag, _):
          # Defer histogram bucketing logic by passing it as a callable to
          # write(), wrapped in a LazyTensorCreator for backwards
          # compatibility, so that we only do this work when summaries are
          # actually written.
          @lazy_tensor_creator.LazyTensorCreator
          def lazy_tensor():
              return _buckets(data, buckets)
  
          return tf.summary.write(
              tag=tag,
              tensor=lazy_tensor,
              step=step,
              metadata=summary_metadata,
          )
  
file_path: tensorboard/tensorboard/plugins/histogram/summary_v2.py
imports: import numpy
  from tensorboard.compat import tf2
  from tensorboard.compat.proto import summary_pb2
  from tensorboard.plugins.histogram import metadata
  from tensorboard.util import lazy_tensor_creator
  from tensorboard.util import tensor_util
label_desc: Use image node_id 2 for calling a global function with example usage: histogram(name, data, step, buckets, description) and returns: tf, _buckets