code: def _init_backend():
      """
      Runs when hypertools is initially imported and sets the matplotlib
      backend used for animated/interactive plots.
      """
      global BACKEND_MAPPING, BACKEND_WARNING, HYPERTOOLS_BACKEND, IPYTHON_INSTANCE, IS_NOTEBOOK, reset_backend, switch_backend
  
      curr_backend = mpl.get_backend()
  
      try:
          # `get_ipython()` function exists in the namespace if
          # `hypertools` was imported from an IPython shell or Jupyter
          # notebook
          IPYTHON_INSTANCE = get_ipython()
          assert "IPKernelApp" in IPYTHON_INSTANCE.config
  
      # NameError: raised if imported from a script
      # AssertionError: raised if imported from an IPython shell
      except (NameError, AssertionError):
          # see `_block_greedy_completer_execution()` docstring
          _block_greedy_completer_execution()
  
          IS_NOTEBOOK = False
          # (excluding WebAgg - no way to test in advance if it will work)
          backends = (
              "TkAgg",
              "QtAgg",
              "Qt5Agg",
              "Qt4Agg",
              "GTK4Agg",
              "GTK3Agg",
              "TkAgg",
              "WXAgg",
          )
          if sys.platform == "darwin":
              # prefer cocoa backend on Mac - pretty much guaranteed to
              # work, appears to be faster, and Mac does NOT like Tkinter
              backends = ("MacOSX", *backends)
  
          # TODO: document setting environment variable
          # check for configurable environment variable
          env_backend = getenv("HYPERTOOLS_BACKEND")
          if env_backend is not None:
              # prefer user-specified backend, if set
              if env_backend.lower() in tuple(map(str.lower, backends)):
                  backends = (
                      backends[: backends.index(HYPERTOOLS_BACKEND)],
                      *backends[
                          backends.index(HYPERTOOLS_BACKEND) + 1 :
                      ],
                  )
  
              backends = (env_backend, *backends)
  
          for b in backends:
              try:
                  mpl.use(b)
                  working_backend = b
                  break
  
              except (ImportError, NameError, ValueError):
                  # ImportError/NameError:
                  #     raised if backend's dependencies aren't installed
                  # ValueError:
                  #     raised if named backed isn't supported by
                  #     installed matplotlib version
                  continue
  
          else:
              BACKEND_WARNING = (
                  "Failed to switch to any interactive backend "
                  f"({', '.join(backends)}). Falling back to 'Agg'."
              )
              working_backend = "Agg"
  
          if (
              env_backend is not None
              and working_backend.lower() != env_backend.lower()
          ):
              # The only time a plotting-related warning should be issued
              # on import rather than on call to hypertools.plot is if
              # $HYPERTOOLS_BACKEND specifies an incompatible backend,
              # since that will have been set manually.
              warnings.warn(
                  "failed to set matplotlib backend to backend "
                  f"specified in environment ('{env_backend}'). "
                  f"Falling back to '{working_backend}'"
              )
  
          switch_backend = reset_backend = _switch_backend_regular
  
      else:
          IS_NOTEBOOK = True
          # if running in a notebook, should almost always use nbAgg. May
          # eventually let user override this with environment variable
          # (e.g., to use ipympl, widget, or WXAgg in JupyterLab), but for
          # now this can be changed manually with
          # `hypertools.set_interactive_backend` or the `mpl_backend`
          # kwarg to `hypertools.plot`
          try:
              mpl.use("nbAgg")
              working_backend = "nbAgg"
          except ImportError:
              BACKEND_WARNING = (
                  "Failed to switch to interactive notebook "
                  "backend ('nbAgg'). Falling back to inline "
                  "static plots."
              )
              working_backend = "inline"
  
          switch_backend = _switch_backend_notebook
          reset_backend = _reset_backend_notebook
  
      finally:
          # restore backend
          mpl.use(curr_backend)
          BACKEND_MAPPING = BackendMapping(BACKEND_KEYS)
          HYPERTOOLS_BACKEND = HypertoolsBackend(
              working_backend
          ).normalize()
  
imports: import inspect
  import sys
  import traceback
  import warnings
  from contextlib import contextmanager, redirect_stdout
  from functools import wraps
  from io import StringIO
  from os import getenv
  from typing import Iterable
  import matplotlib
  import matplotlib.pyplot
  from .._shared.exceptions import HypertoolsBackendError
label_desc: Use image node_id 1 for calling a global function with example usage: _init_backend() without return types