def make_similar_sized_bins(x, n):
    """Utility function to create a set of bins over the range of values in `x`
    such that each bin contains roughly the same number of values.

    Parameters
    ----------
    x : array_like
        The values to be binned.
    n : int
        The number of bins to create.

    Returns
    -------
    bins : ndarray
        An array of bin edges.

    Notes
    -----
    The actual number of bins returned may be less than `n` if `x` contains
    integer values and any single value is represented more than len(x)//n
    times.

    """
    # copy and sort the array
    y = np.array(x).flatten()
    y.sort()

    # setup bins
    bins = [y[0]]

    # determine step size
    step = len(y) // n

    # add bin edges
    for i in range(step, len(y), step):

        # get value at this index
        v = y[i]

        # only add bin edge if larger than previous
        if v > bins[-1]:
            bins.append(v)

    # fix last bin edge
    bins[-1] = y[-1]

    return np.array(bins)