docs: def log_image(self, step, tag, val):
          '''
          Write an image event.
  
          :param int step: Time step (x-axis in TensorBoard graphs)
          :param str tag: Label for this value
          :param numpy.ndarray val: Image in RGB format with values from
              0 to 255; a 3-D array with index order (row, column, channel).
              `val.shape[-1] == 3`
          '''
          # TODO: support floating-point tensors, 4-D tensors, grayscale
          if len(val.shape) != 3:
              raise ValueError('`log_image` value should be a 3-D tensor, instead got shape %s' %
                               (val.shape,))
          if val.shape[2] != 3:
              raise ValueError('Last dimension of `log_image` value should be 3 (RGB), '
                               'instead got shape %s' %
                               (val.shape,))
          fakefile = StringIO()
          png.Writer(size=(val.shape[1], val.shape[0])).write(
              fakefile, val.reshape(val.shape[0], val.shape[1] * val.shape[2]))
          encoded = fakefile.getvalue()
          # https://tensorflow.googlesource.com/tensorflow/+/master/tensorflow/core/framework/summary.proto
          RGB = 3
          image = Summary.Image(height=val.shape[0], width=val.shape[1],
                                colorspace=RGB, encoded_image_string=encoded)
          summary = Summary(value=[Summary.Value(tag=tag, image=image)])
          self._add_event(step, summary)