#!/usr/bin/python3 import csv, os, sys import matplotlib matplotlib.use('Agg') import pylab import matplotlib.pyplot as plt from matplotlib.ticker import MultipleLocator, FormatStrFormatter from matplotlib.transforms import Transform def mapPointsToColor(points): return mapPercentToColor((points - 2)/3.0) def mapPercentToColor(percent): percentTo255 = percent * 255.0 (red, green, blue) = (0, 0, 0) if percentTo255 <= 64: green = percentTo255 * (1.0/64.0) blue = 1.0 elif percentTo255 <= 128: green = 1.0 blue = (128 - percentTo255) * (1.0/64.0) elif percentTo255 <= 192: red = (percentTo255 - 128) * (1.0/64.0) green = 1.0 else: red = 1.0 blue = (255 - percentTo255) * (1.0/64.0) #print percentTo255 #print (red, blue, green) return (red, blue, green) def main(): reader = csv.reader(open('data', 'r'), delimiter='&', skipinitialspace=True) xs = [] ys = [] colors = [] #colorMap = {2: '#330000', 3: '#660000', 4: '#990000', 5: '#CC0000'} colorMap = {2: (.2, 0, 0), 3: (.4, 0, 0), 4: (.6, 0, 0), 5: (.8, 0, 0)} sizes = [] descs = {3: [], 4: [], 5: []} for line in reader: desc = line[0].strip() points = int(line[1].strip()) percent = float(line[3].strip()) cards = int(line[4].strip()) xs.append(percent) ys.append(cards) newColor = mapPointsToColor(points) #print newColor colors.append(newColor) sizes.append(10.0) descs[cards].append((percent, desc, points)) #print descs pylab.ylabel('Number of cards taken') pylab.xlabel('Percentage of 6 card hands that satisfy target') ax = pylab.subplot(111) pylab.scatter(xs, ys, 25, colors, linewidths=(0,)) pylab.axis([0, 50, 2.1, 5.9]) ax.yaxis.set_major_locator(MultipleLocator(1.0)) ax.yaxis.set_major_formatter(FormatStrFormatter('%d')) scatter2 = plt.scatter(-1, -1, marker='o', color=mapPointsToColor(2)) scatter3 = plt.scatter(-1, -1, marker='o', color=mapPointsToColor(3)) scatter4 = plt.scatter(-1, -1, marker='o', color=mapPointsToColor(4)) scatter5 = plt.scatter(-1, -1, marker='o', color=mapPointsToColor(5)) lgd = pylab.legend((scatter2, scatter3, scatter4, scatter5), ('2 points', '3 points', '4 points', '5 points'), scatterpoints=1) #for i in range(4): # lgd.get_lines()[i].set_marker('o') # HACK - we do this to play with the renderer pylab.savefig('targetpoints') renderer = pylab.gca().get_renderer_cache() # Another HACK - draw empty text to get the font info textobj = pylab.text(0, 0, "", size=9, weight='light') fontinfo = textobj._fontproperties for numcards in descs: desclist = descs[numcards] desclist.sort() offsetDesirability = [1, -1, 2, -2, 3, -3] # Map of offsets to the next "safe" x position offsetInfo = {} for (percent, desc, points) in desclist: xpos = percent - .35 textsize = getTextSize(renderer, desc, fontinfo, pylab.gca().transData) offset = 0 # Start with the best offset and take the first one that won't # step on previous text at the same offset. for testOffset in offsetDesirability: if (testOffset not in offsetInfo): offset = testOffset break elif (offsetInfo[testOffset] < xpos): offset = testOffset break offsetInfo[testOffset] = xpos + textsize[0] + 1 textobj = pylab.text(xpos, numcards + offset * .12 - .07, desc, size=9, color=mapPointsToColor(points), weight='light') #offset += 1 #if (offset == 0): # offset += 1 #if (offset == 3): # offset = -3 pylab.savefig('targetpoints') # Returns the size of the text in data coordinates. # This will fail horribly for any sort of nonlinear axes. def getTextSize(renderer, text, properties, transData): (w, h, d) = renderer.get_text_width_height_descent(text, properties, False) (x1, y1) = transData.inverted().transform((0, 0)) (x2, y2) = transData.inverted().transform((w, h)) return (x2-x1, y2-y1) if (__name__ == '__main__'): main()