Create a gist now

Instantly share code, notes, and snippets.

Script that generated histograms over number widths. See http://jensrantil.github.io for an article about this.
import pylab as p
import subprocess
import argparse
from collections import Counter
import numpy as np
import itertools
# See http://jensrantil.github.io/line-styles-in-matplotlib.html.
icolors = itertools.cycle('bgrcmykw')
def number_range(length):
"""Calculate ranges for numbers with certain number of digits.
Example:
>>> number_range(1)
(0, 9)
>>> number_range(2)
(10, 99)
>>> number_range(3)
(100, 999)
"""
assert length > 0
return 0 if length==1 else 10**(length-1), 10**length - 1
def calculate_width(font, size, n):
# Partial cred to http://stackoverflow.com/a/1555556/260805.
cmdtmpl = 'convert -font /Library/Fonts/Microsoft/Times\ New\ Roman.ttf -pointsize 16 label:{0} -trim png:|identify -format "%[fx:w]" -'
return int(subprocess.check_output(cmdtmpl.format(n), shell=True))
def run(args):
p.hold(True)
for digits_in_number in args.digits_in_number:
histogram = Counter((calculate_width(args.font_name, args.font_size, i) for i in
range(*number_range(digits_in_number))))
total = sum(histogram.values())
minval = min(histogram.keys())
maxval = max(histogram.keys())
p.bar(np.arange(minval, maxval+1)-0.5, [1.0 * histogram[v] / total for v in range(minval,
maxval+1)], width=1, label="{} digits".format(digits_in_number), color=next(icolors))
p.legend(loc='upper right', ncol=len(args.digits_in_number))
p.ylabel("normalized frequency")
p.xlabel("number width (pixels)")
p.title('Number width distribution'.format(digits_in_number))
p.show()
def main():
parser = argparse.ArgumentParser(description='Investigates the distribution of number widths for fonts.')
parser.add_argument('digits_in_number', metavar='N', type=int, nargs='+',
help="The number of digits in the number.")
DEFAULT_FONT = '/Library/Fonts/Microsoft/Times\ New\ Roman.ttf'
parser.add_argument('--font-name', metavar="NAME", default=DEFAULT_FONT,
help="Font Image Magick should use. Default: {}".format(DEFAULT_FONT))
DEFAULT_FONT_SIZE = 16
parser.add_argument('--font-size', metavar='SIZE', default=DEFAULT_FONT_SIZE,
type=int, help="Font size in pixels. Default: {}".format(DEFAULT_FONT_SIZE))
args = parser.parse_args()
run(args)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment