Skip to content

Instantly share code, notes, and snippets.

@chbrown
Created October 27, 2013 04:15
Show Gist options
  • Select an option

  • Save chbrown/7177912 to your computer and use it in GitHub Desktop.

Select an option

Save chbrown/7177912 to your computer and use it in GitHub Desktop.
Numpy-powered CLI histogram
import os
import numpy as np
term_rows, term_columns = map(int, os.popen('stty size', 'r').read().split())
def hist(xs, margin=10, width=term_columns):
# I'm not sure why my font in iterm doesn't like \u2588, but it looks weird.
# It's too short and not the right width.
chars = u' \u2581\u2582\u2583\u2584\u2585\u2586\u2587\u2589'
width = term_columns - (2 * (margin + 1))
# compute the histogram values as floats, which is easier, even though we renormalize anyway
hist_values, bin_edges = np.histogram(xs, bins=width, density=True)
# 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
hist_chars = (hist_heights * (len(chars) - 1)).astype(int)
cells = [chars[hist_char] for hist_char in hist_chars]
# margin - size_of_integral_part - 1 (for +/- sign) - 1 (for decimal point) - 1 (because int floors, not ceils)
float_fmt = lambda x: '%.*f' % (margin - int(np.log10(abs(x))) - 3, x)
print '%*s[%s]%-*s' % (margin, float_fmt(bin_edges[0]), u''.join(cells), margin, float_fmt(bin_edges[-1]))
# example:
import scipy.stats
draws = scipy.stats.norm.rvs(size=1000, loc=240, scale=50)
hist(draws)
@chbrown
Copy link
Author

chbrown commented Oct 27, 2013

Example result:

$ py terminal.py
 86.746629[          ▁▁▂▂▁▃▃▃▂▄▅▅▅▅▉▅▇▆▄▅▇▄▃▅▃▃▂▂▁▂▁ ▁▁                      ]471.45819

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment