def create_text_image(text, f, font=gd.gdFontLarge): """ Create image with text. ``text`` is the text which should be printed to the image and ``f`` is an open file-like object. The resulting image is written to ``f`` in PNG format. """ text_width, text_height = gd.fontstrsize(font, text) img = gd.image((text_width + 2, text_height + 2)) black = img.colorAllocate((0, 0, 0)) white = img.colorAllocate((255, 255, 255)) img.fill((0, 0), white) img.string(font, (1, 1), text, black) img.writePng(f)
def __init__(self, cfg): self.cfg = cfg self.refChar = gd.fontstrsize(self.cfg.font, 'W')
def genXScale(cfg, lo, hi, scalePixelLen): maxLabelWidth = gd.fontstrsize(cfg.font, '%d' % hi)[0] return map(lambda x: (str(x[0]),x[1]), genScale(lo, hi, scalePixelLen, scalePixelLen / (maxLabelWidth * 2)))
def plotPoints(self, datapoints, cfg): if len(datapoints) < 2: raise ValueError('Need at least two data points') x_min = x_max = datapoints[0][0] y_min = y_max = datapoints[0][1] # determine data bounds for p in datapoints: x_min = min(x_min, p[0]) x_max = max(x_max, p[0]) y_min = min(y_min, p[1]) y_max = max(y_max, p[1]) img = gd.image(cfg.dim.canvasSize()) img.origin((0,img.size()[1] - 1), 1, -1) img.colorAllocate(cfg.color.background) labelCol = img.colorAllocate(cfg.color.label) gridCol = img.colorAllocate(cfg.color.grid) img.setStyle((gridCol, gridCol, gridCol, gd.gdTransparent, gd.gdTransparent)) planePos = cfg.dim.planePos() planeSize = cfg.dim.planeSize() # plane frame img.line((cfg.dim.yPlaneBorderPos(), cfg.dim.xPlaneBorderPos()), (cfg.dim.yPlaneBorderPos() + planeSize[0], cfg.dim.xPlaneBorderPos()), labelCol) img.line((cfg.dim.yPlaneBorderPos(), cfg.dim.xPlaneBorderPos()), (cfg.dim.yPlaneBorderPos(), cfg.dim.xPlaneBorderPos() + planeSize[1]), labelCol) img.line((cfg.dim.yPlaneBorderPos(), planePos[1] + planeSize[1]),(cfg.dim.yPlaneBorderPos() + planeSize[0] + 1, planePos[1] + planeSize[1]), gridCol) img.line((planePos[0] + planeSize[0],cfg.dim.xPlaneBorderPos()),(planePos[0] + planeSize[0],cfg.dim.xPlaneBorderPos() + planeSize[1] + 1), gridCol) # labels if cfg.label.x: mx = planePos[0] + planeSize[0] / 2 mxl = mx - gd.fontstrsize(cfg.font, cfg.label.x)[0] / 2 img.string(cfg.font, (mxl, cfg.dim.xLabelBaselinePos()), cfg.label.x, labelCol) if cfg.label.y: my = planePos[1] + planeSize[1] / 2 myb = my - gd.fontstrsize(cfg.font, cfg.label.y)[0] / 2 img.stringUp(cfg.font, (cfg.dim.yLabelBaselinePos(), myb), cfg.label.y, labelCol) # area if cfg.renderArea: datapoints.insert(0, (x_min,y_min)) datapoints.append((x_max,y_min)) poly = map(lambda p: ( int(planePos[0] + (planeSize[0] - 1) * (p[0] - x_min) / (x_max - x_min)), int(planePos[1] + (planeSize[1] - 1) * (p[1] - y_min) / (y_max - y_min)) ), datapoints) datapoints.pop(0) datapoints.pop() areaCol = img.colorAllocate(cfg.color.area) img.filledPolygon(poly, areaCol) # hscale & grid labels = genXScale(cfg, x_min, x_max, planeSize[0]) for label in labels: img.string(cfg.font, (planePos[0] + label[1] - gd.fontstrsize(cfg.font, label[0])[0] / 2, cfg.dim.xScaleBaselinePos()), label[0], labelCol) src = (planePos[0] + label[1], cfg.dim.xTicPos()) dst = (planePos[0] + label[1], cfg.dim.xTicPos() + cfg.dim.xTicLen() - 1) img.line(src, dst, labelCol) if cfg.grid: src = (planePos[0] + label[1], planePos[1]) dst = (planePos[0] + label[1], planePos[1] + planeSize[1] - 1) img.line(src, dst, gd.gdStyled) # vscale & grid labels = genYScale(cfg, y_min, y_max, planeSize[1]) for label in labels: img.string(cfg.font, (cfg.dim.yScaleBaselinePos(), planePos[1] + label[1] + cfg.dim.refChar[1] / 2), label[0], labelCol) src = (cfg.dim.yTicPos(), planePos[1] + label[1]) dst = (cfg.dim.yTicPos() + cfg.dim.yTicLen() - 1, planePos[1] + label[1]) img.line(src, dst, labelCol) if cfg.grid: src = (planePos[0], planePos[1] + label[1]) dst = (planePos[0] + planeSize[0] - 1, planePos[1] + label[1]) img.line(src, dst, gd.gdStyled) # graph ink = img.colorAllocate(cfg.color.graph) for i in range(len(datapoints) - 1): dp = datapoints[i] posX = planePos[0] + (planeSize[0] - 1) * (dp[0] - x_min) / (x_max - x_min) posY = planePos[1] + (planeSize[1] - 1) * (dp[1] - y_min) / (y_max - y_min) src = (int(posX), int(posY)) dp = datapoints[i+1] posX = planePos[0] + (planeSize[0] - 1) * (dp[0] - x_min) / (x_max - x_min) posY = planePos[1] + (planeSize[1] - 1) * (dp[1] - y_min) / (y_max - y_min) dst = (int(posX), int(posY)) img.line(src, dst, ink) return img
def make_map(filename, exclusive, props, image_filename, item): hit = CounterSet() miss = CounterSet() nr = CounterSet() item_lower = item.lower() for row in csv.reader(file(filename, 'rb')): item = row[0].lower() comm = community(row[1]) if ((exclusive and item_lower == item) or (not exclusive and item.find(item_lower) != -1)): hit.occur += 1 hit << comm elif item in ('-0-', 'nr', 'na'): nr.occur += 1 nr << comm else: miss.occur += 1 miss << comm coords_file = props['map.coords'] coords = {} for line in file(coords_file): (infid, xy) = line.strip().split(':') coords[infid] = tuple(map(int, xy.split(','))) img = gd.image(props['map.image']) black = img.colorAllocate((0, 0, 0)) red = img.colorAllocate((255, 0, 0)) for h in hit: (x, y) = coords[h] img.filledRectangle((x-3, y-3), (x+4, y+4), red) img.rectangle((x-3, y-3), (x+4, y+4), black) for m in (miss-hit): (x, y) = coords[m] img.rectangle((x-3, y-3), (x+3, y+3), black) for n in (nr-(hit+miss)): (x, y) = coords[n] img.line((x-3, y-3), (x+4, y+4), black) img.line((x-3, y+4), (x+4, y-3), black) (line_width, line_height) = gd.fontstrsize(gd.gdFontLarge, 'M') x = int(props['map.text.x']) y = int(props['map.text.y']) img.filledRectangle((x, y+4), (x+7, y+11), red) img.rectangle((x, y+4), (x+7, y+11), black) img.string(gd.gdFontLarge, (x+17, y), item, black) y += line_height img.string(gd.gdFontLarge, (x+27, y), 'Occurrences (%d)' % hit.occur, black) y += line_height img.string(gd.gdFontLarge, (x+27, y), 'Communities (%d)' % len(hit), black) y += line_height img.rectangle((x, y+4), (x+7, y+11), black) img.string(gd.gdFontLarge, (x+17, y), 'Other Reseponses', black) y += line_height img.string(gd.gdFontLarge, (x+27, y), 'Occurrences (%d)' % miss.occur, black) y += line_height img.string(gd.gdFontLarge, (x+27, y), 'Communities (%d)' % len(miss), black) y += line_height img.line((x, y+4), (x+7, y+11), black) img.line((x, y+11), (x+7, y+4), black) img.string(gd.gdFontLarge, (x+17, y), 'No Response', black) y += line_height img.string(gd.gdFontLarge, (x+27, y), 'Occurrences (%d)' % nr.occur, black) y += line_height img.string(gd.gdFontLarge, (x+27, y), 'Communities (%d)' % len(nr), black) img.writePng(image_filename) return True
def genXScale(cfg, lo, hi, scalePixelLen): maxLabelWidth = gd.fontstrsize(cfg.font, '%d' % hi)[0] return map( lambda x: (str(x[0]), x[1]), genScale(lo, hi, scalePixelLen, scalePixelLen / (maxLabelWidth * 2)))
def plotPoints(self, datapoints, cfg): if len(datapoints) < 2: raise ValueError('Need at least two data points') x_min = x_max = datapoints[0][0] y_min = y_max = datapoints[0][1] # determine data bounds for p in datapoints: x_min = min(x_min, p[0]) x_max = max(x_max, p[0]) y_min = min(y_min, p[1]) y_max = max(y_max, p[1]) img = gd.image(cfg.dim.canvasSize()) img.origin((0, img.size()[1] - 1), 1, -1) img.colorAllocate(cfg.color.background) labelCol = img.colorAllocate(cfg.color.label) gridCol = img.colorAllocate(cfg.color.grid) img.setStyle( (gridCol, gridCol, gridCol, gd.gdTransparent, gd.gdTransparent)) planePos = cfg.dim.planePos() planeSize = cfg.dim.planeSize() # plane frame img.line((cfg.dim.yPlaneBorderPos(), cfg.dim.xPlaneBorderPos()), (cfg.dim.yPlaneBorderPos() + planeSize[0], cfg.dim.xPlaneBorderPos()), labelCol) img.line((cfg.dim.yPlaneBorderPos(), cfg.dim.xPlaneBorderPos()), (cfg.dim.yPlaneBorderPos(), cfg.dim.xPlaneBorderPos() + planeSize[1]), labelCol) img.line((cfg.dim.yPlaneBorderPos(), planePos[1] + planeSize[1]), (cfg.dim.yPlaneBorderPos() + planeSize[0] + 1, planePos[1] + planeSize[1]), gridCol) img.line((planePos[0] + planeSize[0], cfg.dim.xPlaneBorderPos()), (planePos[0] + planeSize[0], cfg.dim.xPlaneBorderPos() + planeSize[1] + 1), gridCol) # labels if cfg.label.x: mx = planePos[0] + planeSize[0] / 2 mxl = mx - gd.fontstrsize(cfg.font, cfg.label.x)[0] / 2 img.string(cfg.font, (mxl, cfg.dim.xLabelBaselinePos()), cfg.label.x, labelCol) if cfg.label.y: my = planePos[1] + planeSize[1] / 2 myb = my - gd.fontstrsize(cfg.font, cfg.label.y)[0] / 2 img.stringUp(cfg.font, (cfg.dim.yLabelBaselinePos(), myb), cfg.label.y, labelCol) # area if cfg.renderArea: datapoints.insert(0, (x_min, y_min)) datapoints.append((x_max, y_min)) poly = map( lambda p: (int(planePos[0] + (planeSize[0] - 1) * (p[0] - x_min) / (x_max - x_min)), int(planePos[1] + (planeSize[1] - 1) * (p[1] - y_min) / (y_max - y_min))), datapoints) datapoints.pop(0) datapoints.pop() areaCol = img.colorAllocate(cfg.color.area) img.filledPolygon(poly, areaCol) # hscale & grid labels = genXScale(cfg, x_min, x_max, planeSize[0]) for label in labels: img.string(cfg.font, (planePos[0] + label[1] - gd.fontstrsize(cfg.font, label[0])[0] / 2, cfg.dim.xScaleBaselinePos()), label[0], labelCol) src = (planePos[0] + label[1], cfg.dim.xTicPos()) dst = (planePos[0] + label[1], cfg.dim.xTicPos() + cfg.dim.xTicLen() - 1) img.line(src, dst, labelCol) if cfg.grid: src = (planePos[0] + label[1], planePos[1]) dst = (planePos[0] + label[1], planePos[1] + planeSize[1] - 1) img.line(src, dst, gd.gdStyled) # vscale & grid labels = genYScale(cfg, y_min, y_max, planeSize[1]) for label in labels: img.string(cfg.font, (cfg.dim.yScaleBaselinePos(), planePos[1] + label[1] + cfg.dim.refChar[1] / 2), label[0], labelCol) src = (cfg.dim.yTicPos(), planePos[1] + label[1]) dst = (cfg.dim.yTicPos() + cfg.dim.yTicLen() - 1, planePos[1] + label[1]) img.line(src, dst, labelCol) if cfg.grid: src = (planePos[0], planePos[1] + label[1]) dst = (planePos[0] + planeSize[0] - 1, planePos[1] + label[1]) img.line(src, dst, gd.gdStyled) # graph ink = img.colorAllocate(cfg.color.graph) for i in range(len(datapoints) - 1): dp = datapoints[i] posX = planePos[0] + (planeSize[0] - 1) * (dp[0] - x_min) / (x_max - x_min) posY = planePos[1] + (planeSize[1] - 1) * (dp[1] - y_min) / (y_max - y_min) src = (int(posX), int(posY)) dp = datapoints[i + 1] posX = planePos[0] + (planeSize[0] - 1) * (dp[0] - x_min) / (x_max - x_min) posY = planePos[1] + (planeSize[1] - 1) * (dp[1] - y_min) / (y_max - y_min) dst = (int(posX), int(posY)) img.line(src, dst, ink) return img