Restrict histogram to bins whose data values (not bin numbers) along axis are between start and stop
        (both inclusive). Returns d dimensional histogram.
173173
def slice(self, start, stop=None, axis=0):
        """"""
        if stop is None:
            # Make a 1=bin slice
            stop = start
        axis = self.get_axis_number(axis)
        start_bin = max(0, self.get_axis_bin_index(start, axis))
        stop_bin = min(len(self.bin_centers(axis)) - 1,  # TODO: test off by one!
                       self.get_axis_bin_index(stop, axis))
        new_bin_edges = self.bin_edges.copy()
        new_bin_edges[axis] = new_bin_edges[axis][start_bin:stop_bin + 2]   # TODO: Test off by one here!
        return Histdd.from_histogram(np.take(self.histogram, np.arange(start_bin, stop_bin + 1), axis=axis),
                                     bin_edges=new_bin_edges, axis_names=self.axis_names)
527879
def histogram(a, bins):
    
    if any(map(lambda x: x < 0, diff(bins))):
        raise ValueError(
            'bins must increase monotonically.')

    try:
        sa = sorted(a)
    except TypeError:
        # Perhaps just a single value? Treat as a list and carry on
        sa = sorted([a])

    # import numpy as np
    # nl = np.searchsorted(sa, bins[:-1], 'left')
    # nr = np.searchsorted(sa, bins[-1], 'right')
    # nn = np.r_[nl, nr]
    #
    # # cl = list(accumulate(Counter(map(lambda x: bisect_left(bins[:-1], x), sa)))
    # # print("cl")
    # # print([cl[i] for i in range(len(bins))])
    # print("nl")
    # print(list(nl))
    # # print(Counter(map(lambda x: bisect_right([bins[-1]], x), sa)))
    # print("nr")
    # print([nr])
    # print("nn")
    # print(list(nn))
    # print("hist")
    # print(list(np.diff(nn)))
    # print(list(np.histogram(a, bins)[0]))

    nl = list(accumulate([Counter(map(lambda x: bisect_left(bins[:-1], x), sa))[i] for i in range(len(bins) - 1)]))
    # print("nl")
    # print(nl)
    nr = Counter(map(lambda x: bisect_right([bins[1]], x), sa))[1]
    # print(nl)
    # print(nr)
    n = list(nl) + [nr]

    return diff(n), bins
431512
def _areadist(ax, v, xr, c, bins=100, by=None, alpha=1, label=None):
    
    y, x = np.histogram(v[~np.isnan(v)], bins)
    x = x[:-1]

    if by is None:
        by = np.zeros((bins,))

    ax.fill_between(x, y, by, facecolor=c, alpha=alpha, label=label)
    return y
1014533
def hist2d(x, y, label=None, opacity=None):
    
    x = np.atleast_1d(x)
    y = np.atleast_1d(y)
    data = [go.Histogram2d(x=x, y=y, opacity=opacity, name=label)]
    return Chart(data=data)
199826
def has_same_bins(self, other: "HistogramBase") -> bool:
        """"""
        if self.shape != other.shape:
            return False
        elif self.ndim == 1:
            return np.allclose(self.bins, other.bins)
        elif self.ndim > 1:
            for i in range(self.ndim):
                if not np.allclose(self.bins[i], other.bins[i]):
                    return False
            return True
542560
def empty_clone(self, binning=None, axis=0, type=None, **kwargs):
        
        ndim = self.GetDimension()
        if binning is False and ndim == 1:
            raise ValueError(
                "cannot remove the x-axis of a 1D histogram")
        args = []
        for iaxis in range(ndim):
            if iaxis == axis:
                if binning is False:
                    # skip this axis
                    continue
                elif binning is not None:
                    if hasattr(binning, '__iter__'):
                        binning = (binning,)
                    args.extend(binning)
                    continue
            args.append(list(self._edges(axis=iaxis)))
        if type is None:
            type = self.TYPE
        if binning is False:
            ndim -= 1
        cls = [Hist, Hist2D, Hist3D][ndim - 1]
        return cls(*args, type=type, **kwargs)
1252388
def lowerbound(self, axis=0):
        
        if not 0 <= axis < self.GetDimension():
            raise ValueError(
                "axis must be a non-negative integer less than "
                "the dimensionality of the histogram")
        if axis == 0:
            return self.xedges(1)
        if axis == 1:
            return self.yedges(1)
        if axis == 2:
            return self.zedges(1)
        raise TypeError("axis must be an integer")
881137
def ansi_format( self, width=64, height=12 ):
        
        from mrcrowbar.ansi import format_bar_graph_iter
        if (256 % width) != 0:
            raise ValueError( 'Width of the histogram must be a divisor of 256' )
        elif (width <= 0):
            raise ValueError( 'Width of the histogram must be greater than zero' )
        elif (width > 256):
            raise ValueError( 'Width of the histogram must be less than or equal to 256' )
    
        buckets = self.histogram( width )
        result = []
        for line in format_bar_graph_iter( buckets, width=width, height=height ):
            result.append( ' {}\n'.format( line ) )

        result.append( '╘'+('═'*width)+'╛\n' )
        result.append( 'entropy: {:.10f}\n'.format( self.entropy ) )
        result.append( 'samples: {}'.format( self.samples ) )
        return ''.join( result )
1096599
def remove_bins_with_ends_out_of_bounds(df, chromosome_size,
                                        window_size):
    # type: (pd.DataFrame, int, int) -> pd.DataFrame
    """"""

    # The dataframe is empty and contains no bins out of bounds

    # print(df.head(2))
    # print(chromosome_size)
    # print(window_size)
    out_of_bounds = df[df.index.get_level_values("Bin") + window_size >
                       chromosome_size].index
    # print(len(out_of_bounds))
    df = df.drop(out_of_bounds)

    return df
325220
def all_axis_bin_centers(self, axis):
        """"""
        # Arcane hack that seems to work, at least in 3d... hope
        axis = self.get_axis_number(axis)
        return np.meshgrid(*self.bin_centers(), indexing='ij')[axis]
612093
def range_hist(items, bins):
    
    big_hist = ut.dict_hist(items)
    hist = ut.odict([(b, 0) for b in bins])

    for k, v in big_hist.items():
        for b in bins:
            if isinstance(b, (list, tuple)):
                if k >= b[0] and k < b[1]:
                    hist[b] += v
            elif k == b:
                hist[b] += v
    return hist
909998
def _get_bin_width(stdev, count):
    

    w = int(round((3.5 * stdev) / (count ** (1.0 / 3))))
    if w:
        return w
    else:
        return 1
484331
def fist() -> Histogram1D:
    """"""
    import numpy as np
    from ..histogram1d import Histogram1D
    widths = [0, 1.2, 0.2, 1, 0.1, 1, 0.1, 0.9, 0.1, 0.8]
    edges = np.cumsum(widths)
    heights = np.asarray([4, 1, 7.5, 6, 7.6, 6, 7.5, 6, 7.2]) + 5
    return Histogram1D(edges, heights, axis_name="Is this a fist?", title="Physt \"logo\"")
679214
def edges(self):
        ""
        if util.config.future_deprecations:
            self.param.warning('Histogram.edges is deprecated in favor of '
                               'common dimension_values method.')
        return self.interface.coords(self, self.kdims[0], edges=True)
614103
def projection(self, axis):
        """"""
        axis = self.get_axis_number(axis)
        projected_hist = np.sum(self.histogram, axis=self.other_axes(axis))
        return Hist1d.from_histogram(projected_hist, bin_edges=self.bin_edges[axis])
1028624
def get_squeeze_dims(xarray_obj,
                     dim: Union[Hashable, Iterable[Hashable], None] = None,
                     axis: Union[int, Iterable[int], None] = None
                     ) -> List[Hashable]:
    
    if dim is not None and axis is not None:
        raise ValueError('cannot use both parameters `axis` and `dim`')
    if dim is None and axis is None:
        return [d for d, s in xarray_obj.sizes.items() if s == 1]

    if isinstance(dim, Iterable) and not isinstance(dim, str):
        dim = list(dim)
    elif dim is not None:
        dim = [dim]
    else:
        assert axis is not None
        if isinstance(axis, int):
            axis = [axis]
        axis = list(axis)
        if any(not isinstance(a, int) for a in axis):
            raise TypeError(
                'parameter `axis` must be int or iterable of int.')
        alldims = list(xarray_obj.sizes.keys())
        dim = [alldims[a] for a in axis]

    if any(xarray_obj.sizes[k] > 1 for k in dim):
        raise ValueError('cannot select a dimension to squeeze out '
                         'which has length greater than one')
    return dim
1214607
def on_separate_dimensions(self):
        
        if np.any([isinstance(k.active_dims, slice) for k in self.kernels]):
            # Be conservative in the case of a slice object
            return False
        else:
            dimlist = [k.active_dims for k in self.kernels]
            overlapping = False
            for i, dims_i in enumerate(dimlist):
                for dims_j in dimlist[i + 1:]:
                    if np.any(dims_i.reshape(-1, 1) == dims_j.reshape(1, -1)):
                        overlapping = True
            return not overlapping