class_docstr: Calculate and show a spectrogram
  
  Parameters
  ----------
  x : array-like
      1D signal to operate on. ``If len(x) < n_fft``, x will be
      zero-padded to length ``n_fft``.
  n_fft : int
      Number of FFT points. Much faster for powers of two.
  step : int | None
      Step size between calculations. If None, ``n_fft // 2``
      will be used.
  fs : float
      The sample rate of the data.
  window : str | None
      Window function to use. Can be ``'hann'`` for Hann window, or None
      for no windowing.
  normalize : bool
      Normalization of spectrogram values across frequencies.
  color_scale : {'linear', 'log'}
      Scale to apply to the result of the STFT.
      ``'log'`` will use ``10 * log10(power)``.
  cmap : str
      Colormap name.
  clim : str | tuple
      Colormap limits. Should be ``'auto'`` or a two-element tuple of
      min and max values.
code: def _calculate_spectrogram(self):
      if self._x is not None:
          x = self._x
          nan_mean = np.nanmean(x)
          idx = np.isnan(x)
          x[idx] = nan_mean
          data = stft(
              x, self._n_fft, self._step, self._fs, self._window
          )
          data = np.abs(data)
          data = (
              20 * np.log10(data)
              if self._color_scale == "log"
              else data
          )
          if self._normalize:
              for i in range(data.shape[0]):
                  data[i, :] -= np.mean(data[i, :])
                  data[i, :] /= np.std(data[i, :])
          return data.astype(
              np.float32
          )  # ImageVisual will warn if 64-bit
      else:
          return None
  
imports: import numpy
  from .image import ImageVisual
  from ..util.fourier import stft, fft_freqs
label_desc: Use image node_id 17 for calling the SpectrogramVisual obj's underlying member method code with example usage: obj._calculate_spectrogram() and returns: data, None