docs: def calculate_bins(array, _=None, *args, **kwargs) -> BinningBase:
      """Find optimal binning from arguments.
  
      Parameters
      ----------
      array: arraylike
          Data from which the bins should be decided (sometimes used, sometimes not)
      _: int or str or Callable or arraylike or Iterable or BinningBase
          To-be-guessed parameter that specifies what kind of binning should be done
      check_nan: bool
          Check for the presence of nan's in array? Default: True
      range: tuple
          Limit values to a range. Some of the binning methods also (subsequently)
          use this parameter for the bin shape.
  
      Returns
      -------
      BinningBase
          A two-dimensional array with pairs of bin edges (not necessarily consecutive).
  
      """
      if array is not None:
          if kwargs.pop("check_nan", True):
              if np.any(np.isnan(array)):
                  raise RuntimeError("Cannot calculate bins in presence of NaN's.")
          if kwargs.get("range", None):   # TODO: re-consider the usage of this parameter
              array = array[(array >= kwargs["range"][0]) & (array <= kwargs["range"][1])]
      if _ is None:
          bin_count = 10  # kwargs.pop("bins", ideal_bin_count(data=array)) - same as numpy
          binning = numpy_binning(array, bin_count, *args, **kwargs)
      elif isinstance(_, BinningBase):
          binning = _
      elif isinstance(_, int):
          binning = numpy_binning(array, _, *args, **kwargs)
      elif isinstance(_, str):
          # What about the ranges???
          if _ in bincount_methods:
              bin_count = ideal_bin_count(array, method=_)
              binning = numpy_binning(array, bin_count, *args, **kwargs)
          elif _ in binning_methods:
              method = binning_methods[_]
              binning = method(array, *args, **kwargs)
          else:
              raise RuntimeError("No binning method {0} available.".format(_))
      elif callable(_):
          binning = _(array, *args, **kwargs)
      elif np.iterable(_):
          binning = static_binning(array, _, *args, **kwargs)
      else:
          raise RuntimeError("Binning {0} not understood.".format(_))
      return binning