def hist(xs, range=None, margin=10, width=None):
    '''
    xs: array of numbers, preferably an np.array, can contain nans, infinities
    range: (minimum, maximum) tuple of numbers (defaults to (min, max) of xs)
    margin: number of characters to use for the min-max labels (default: 10)
    width: number of characters that will fit in a row (defaults to your terminal width)

    Example:

    >>> import scipy.stats
    >>> draws = scipy.stats.norm.rvs(size=100, loc=100, scale=10)
    >>> hist(draws, margin=5)
    '''
    if width is None:
        width = terminal.width()

    # add 1 to each margin for the [ and ] brackets
    n_bins = width - (2 * (margin + 1))
    # wrap it up as an array so we can index into it with a bool array. most likely it'll be a numpy array already
    xs = np.array(xs)
    finite = np.isfinite(xs)
    # don't copy it unless we need to (we don't need to if there are only finite numbers)
    # but if there are some nans / infinities, remove them
    finite_xs = xs[finite]  # if nonfinite.any() else xs
    # compute the histogram values as floats, which is easier, even though we renormalize anyway
    hist_values, bin_edges = np.histogram(finite_xs, bins=n_bins, density=True, range=range)
    # we want the highest hist_height to be 1.0
    hist_heights = hist_values / max(hist_values)
    # np.array(...).astype(int) will floor each value, if we wanted
    hist_chars = (hist_heights * (len(terminal.bars) - 1)).astype(int)
    cells = [terminal.bars[hist_char] for hist_char in hist_chars]

    print format_number_line(cells, bin_edges[0], bin_edges[-1], margin=margin)
    if not finite.all():
        # if we took any out, report it:
        nonfinite_xs = xs[~finite]
        neginf = np.isneginf(nonfinite_xs)
        nan = np.isnan(nonfinite_xs)
        posinf = np.isposinf(nonfinite_xs)
        print '%s %s %s' % (
            ('(%d) -inf' % np.count_nonzero(neginf) if neginf.any() else '').rjust(margin),
            ('(%d) nan' % np.count_nonzero(nan) if nan.any() else '').center(len(cells)),
            ('(%d) +inf' % np.count_nonzero(posinf) if posinf.any() else '').ljust(margin)
        )
def hist ( xs , range = None , margin = 10 , width = None ) : if width is None : width = terminal . width ( ) n_bins = width - ( 2 * ( margin + 1 ) ) xs = np . array ( xs ) finite = np . isfinite ( xs ) finite_xs = xs [ finite ] hist_values , bin_edges = np . histogram ( finite_xs , bins = n_bins , density = True , range = range ) hist_heights = hist_values / max ( hist_values ) hist_chars = ( hist_heights * ( len ( terminal . bars ) - 1 ) ) . astype ( int ) cells = [ terminal . bars [ hist_char ] for hist_char in hist_chars ] print format_number_line ( cells , bin_edges [ 0 ] , bin_edges [ - 1 ] , margin = margin ) if not finite . all ( ) : nonfinite_xs = xs [ ~ finite ] neginf = np . isneginf ( nonfinite_xs ) nan = np . isnan ( nonfinite_xs ) posinf = np . isposinf ( nonfinite_xs ) print '%s %s %s' % ( ( '(%d) -inf' % np . count_nonzero ( neginf ) if neginf . any ( ) else '' ) . rjust ( margin ) , ( '(%d) nan' % np . count_nonzero ( nan ) if nan . any ( ) else '' ) . center ( len ( cells ) ) , ( '(%d) +inf' % np . count_nonzero ( posinf ) if posinf . any ( ) else '' ) . ljust ( margin ) )
xs: array of numbers, preferably an np.array, can contain nans, infinities
    range: (minimum, maximum) tuple of numbers (defaults to (min, max) of xs)
    margin: number of characters to use for the min-max labels (default: 10)
    width: number of characters that will fit in a row (defaults to your terminal width)

    Example:

    >>> import scipy.stats
    >>> draws = scipy.stats.norm.rvs(size=100, loc=100, scale=10)
    >>> hist(draws, margin=5)