code: def _plot_ica_properties(
      pick,
      ica,
      inst,
      psds_mean,
      freqs,
      n_trials,
      epoch_var,
      plot_lowpass_edge,
      epochs_src,
      set_title_and_labels,
      plot_std,
      psd_ylabel,
      spectrum_std,
      log_scale,
      topomap_args,
      image_args,
      fig,
      axes,
      kind,
      dropped_indices,
  ):
      """Plot ICA properties (helper)."""
      from mpl_toolkits.axes_grid1.axes_divider import (
          make_axes_locatable,
      )
  
      topo_ax, image_ax, erp_ax, spec_ax, var_ax = axes
  
      # plotting
      # --------
      # component topomap
      _plot_ica_topomap(
          ica, pick, show=False, axes=topo_ax, **topomap_args
      )
      topo_ax._ch_type = _get_plot_ch_type(
          ica,
          ch_type=None,
          allow_ref_meg=ica.allow_ref_meg,
      )
  
      # image and erp
      # we create a new epoch with dropped rows
      epoch_data = epochs_src.get_data(copy=False)
      epoch_data = np.insert(
          arr=epoch_data,
          obj=(
              dropped_indices - np.arange(len(dropped_indices))
          ).astype(int),
          values=0.0,
          axis=0,
      )
      from ..epochs import EpochsArray
  
      epochs_src = EpochsArray(
          epoch_data, epochs_src.info, tmin=epochs_src.tmin, verbose=0
      )
  
      plot_epochs_image(
          epochs_src,
          picks=pick,
          axes=[image_ax, erp_ax],
          combine=None,
          colorbar=False,
          show=False,
          **image_args,
      )
  
      # spectrum
      spec_ax.plot(freqs, psds_mean, color="k")
      if plot_std:
          spec_ax.fill_between(
              freqs,
              psds_mean - spectrum_std[0],
              psds_mean + spectrum_std[1],
              color="k",
              alpha=0.2,
          )
      if plot_lowpass_edge:
          spec_ax.axvline(
              inst.info["lowpass"],
              lw=2,
              linestyle="--",
              color="k",
              alpha=0.2,
          )
  
      # epoch variance
      var_ax_divider = make_axes_locatable(var_ax)
      hist_ax = var_ax_divider.append_axes(
          "right", size="33%", pad="2.5%"
      )
      var_ax.scatter(
          range(len(epoch_var)),
          epoch_var,
          alpha=0.5,
          facecolor=[0, 0, 0],
          lw=0,
      )
      # rejected epochs in red
      var_ax.scatter(
          dropped_indices,
          epoch_var[dropped_indices],
          alpha=1.0,
          facecolor=[1, 0, 0],
          lw=0,
      )
      # compute percentage of dropped epochs
      var_percent = (
          float(len(dropped_indices)) / float(len(epoch_var)) * 100.0
      )
  
      # histogram & histogram
      _, counts, _ = hist_ax.hist(
          epoch_var, orientation="horizontal", color="k", alpha=0.5
      )
  
      # kde
      ymin, ymax = hist_ax.get_ylim()
      try:
          kde = gaussian_kde(epoch_var)
      except np.linalg.LinAlgError:
          pass  # singular: happens when there is nothing plotted
      else:
          x = np.linspace(ymin, ymax, 50)
          kde_ = kde(x)
          kde_ /= kde_.max() or 1.0
          kde_ *= hist_ax.get_xlim()[-1] * 0.9
          hist_ax.plot(kde_, x, color="k")
          hist_ax.set_ylim(ymin, ymax)
  
      # aesthetics
      # ----------
      set_title_and_labels(
          image_ax, kind + " image and ERP/ERF", [], kind
      )
  
      # erp
      set_title_and_labels(erp_ax, [], "Time (s)", "AU")
      erp_ax.spines["right"].set_color("k")
      erp_ax.set_xlim(epochs_src.times[[0, -1]])
      # remove half of yticks if more than 5
      yt = erp_ax.get_yticks()
      if len(yt) > 5:
          erp_ax.yaxis.set_ticks(yt[::2])
  
      # remove xticks - erp plot shows xticks for both image and erp plot
      image_ax.xaxis.set_ticks([])
      yt = image_ax.get_yticks()
      image_ax.yaxis.set_ticks(yt[1:])
      image_ax.set_ylim([-0.5, n_trials + 0.5])
  
      def _set_scale(ax, scale):
          """Set the scale of a matplotlib axis."""
          ax.set_xscale(scale)
          ax.set_yscale(scale)
          ax.relim()
          ax.autoscale()
  
      # spectrum
      set_title_and_labels(
          spec_ax, "Spectrum", "Frequency (Hz)", psd_ylabel
      )
      spec_ax.yaxis.labelpad = 0
      spec_ax.set_xlim(freqs[[0, -1]])
      ylim = spec_ax.get_ylim()
      air = np.diff(ylim)[0] * 0.1
      spec_ax.set_ylim(ylim[0] - air, ylim[1] + air)
      image_ax.axhline(0, color="k", linewidth=0.5)
      if log_scale:
          _set_scale(spec_ax, "log")
  
      # epoch variance
      var_ax_title = "Dropped segments: %.2f %%" % var_percent
      set_title_and_labels(var_ax, var_ax_title, kind, "Variance (AU)")
  
      hist_ax.set_ylabel("")
      hist_ax.set_yticks([])
      set_title_and_labels(hist_ax, None, None, None)
  
      def _plot_ica_properties_on_press(event, ica, pick, topomap_args):
          """Handle keypress events for ica properties plot."""
          import matplotlib.pyplot as plt
  
          fig = event.canvas.figure
          if event.key == "escape":
              plt.close(fig)
          if event.key in ("t", "l"):
              ax_labels = [ax.get_label() for ax in fig.axes]
              if event.key == "t":
                  ax = fig.axes[ax_labels.index("topomap")]
                  ax.clear()
                  ch_types = list(set(ica.get_channel_types()))
                  ch_type = ch_types[
                      (ch_types.index(ax._ch_type) + 1) % len(ch_types)
                  ]
                  _plot_ica_topomap(
                      ica,
                      pick,
                      ch_type=ch_type,
                      show=False,
                      axes=ax,
                      **topomap_args,
                  )
                  ax._ch_type = ch_type
              elif event.key == "l":
                  ax = fig.axes[ax_labels.index("spectrum")]
                  _set_scale(
                      ax,
                      "linear" if ax.get_xscale() == "log" else "log",
                  )
              del ax
              fig.canvas.draw()
  
      # add keypress event handler
      fig.canvas.mpl_connect(
          "key_press_event",
          lambda event: _plot_ica_properties_on_press(
              event, ica, pick, topomap_args
          ),
      )
  
      return fig
  
imports: import warnings
  from functools import partial
  import numpy
  from scipy.stats import gaussian_kde
  from .._fiff.meas_info import create_info
  from .._fiff.pick import _picks_to_idx, pick_types
  from .._fiff.proj import _has_eeg_average_ref_proj
  from ..defaults import DEFAULTS, _handle_default
  from ..utils import _reject_data_segments, _validate_type, fill_doc, verbose
  from .epochs import plot_epochs_image
  from .evoked import _butterfly_on_button_press, _butterfly_onpick
  from .topomap import _plot_ica_topomap
  from .utils import _compute_scalings, _convert_psds, _get_cmap, _get_plot_ch_type, _handle_precompute, _make_event_color_dict, plt_show
label_desc: Use image node_id 3 for calling a global function with example usage: _plot_ica_properties(pick, ica, inst, psds_mean, freqs, n_trials, epoch_var, plot_lowpass_edge, epochs_src, set_title_and_labels, plot_std, psd_ylabel, spectrum_std, log_scale, topomap_args, image_args, fig, axes, kind, dropped_indices) and returns: fig