def createChart(img, yLevel, ydist, xlabel, ylabel, header, font=ImageFont.load_default()): """Creates the chart environment and pastes the given img onto it. Returns PIL image object showing a patterngram """ #init colorBG=(255, 255, 255) colorFG=(0, 0, 0) margin = 50 #create image chartImg = Image.new("RGB", (img.size[0]+(2*margin), img.size[1]+(2*margin)), colorBG) #paste image to chart chartImg.paste(img, (margin+1, margin+1)) draw = ImageDraw.Draw(chartImg) #draw border borderY2 = img.size[1]+margin+1 draw.rectangle(((margin, margin), (img.size[0]+margin+1, borderY2)), outline=colorFG) #x-label labelSize = computeLabelDist(img.size[0], mode=0) for x in xrange(img.size[0]): if x%100==0: s = 4 elif x%50==0: s = 3 elif x%10==0: s = 2 elif x%5==0: s = 1 else: s = 0 #draw upper border draw.line((x+margin, margin, x+margin, margin-s), fill=colorFG) #draw lower border draw.line((x+margin, borderY2, x+margin, borderY2+s), fill=colorFG) #draw labels if x%labelSize==0: label = str(x) pos = (margin + x - (font.getsize(label)[0]/2), borderY2+5) draw.text(pos, label, fill=colorFG, font=font) #y-label labelSize = computeLabelDist(yLevel, mode=1) for y in xrange(yLevel+1): if y%5==0: s = 3 else: s = 1 ypos = borderY2 - (y * ydist) #left border draw.line((margin-s, ypos, margin, ypos), fill=colorFG) #right border draw.line((margin+1+img.size[0], ypos, margin+1+img.size[0]+s, ypos), fill=colorFG) #draw labels if y%labelSize==0 and y!=0: label = str(y) pos = (margin - (font.getsize(label)[0]+4), borderY2-(y*ydist)-(font.getsize(label)[1]/2)) draw.text(pos, label, fill=colorFG, font=font) #===draw labels=== #xlabel draw.text((margin+(img.size[0]/2)-(font.getsize(xlabel)[0]/2), borderY2+(margin/2)), xlabel, fill=colorFG, font=font) #header draw.text((margin+(img.size[0]/2)-(font.getsize(header)[0]/2), margin/2), header, fill=colorFG, font=font) #ylabel yLabelImg = rotText(ylabel, font) chartImg.paste(yLabelImg, ((margin/2)-(yLabelImg.size[0]/2), margin+(img.size[1]/2)-(yLabelImg.size[1]/2))) #clean up del yLabelImg del draw del font #return created chart image return chartImg
def createHeatmapChart(matrix, xLabels, yLabels, scopes = [0.2, 0.4, 0.6, 0.8, 1], recSize = 20, colorBG = (255, 255, 255), colorFG = (0, 0, 0), colorChartBG = (230, 230, 230), colorGrid = (100, 100, 100), font = ImageFont.load_default()): """Creates a heatmap chart for the given values in the matrix labeled with the labels given in xDict and yDict TODO: options: - scopes - list of values that describe the scopes for the matrix values, e.g. scopes = [0.2, 0.4, 0.6, 0.8, 1] (default) - font - font used - recSize - size of a single indicator rectangle in the heatmap - colorBG - background color of the chart as rgb value (default: (255, 255, 255)) - colorFG - foreground color of the chart as rgb value (default: (0, 0, 0)) - colorChartBG - background color of the chart as rgb value (default: (230, 230, 230)) - colorGrid - color of the grid as rgb value (dafault: (100, 100, 100)); if set to "None" no grid will be drawn """ #===init=== #margin to left and bottom margin = 5 #maximal identifier length maxIdLength = computeMaxIdLength(set(xLabels+yLabels), font) #size of the img maxX = margin + maxIdLength + ((len(xLabels)+2) * recSize) maxY = margin + maxIdLength + (len(yLabels)+2) * recSize #lower left corner fo the chart offset = (margin+maxIdLength+4, maxY-maxIdLength-margin) #===create img=== img = Image.new("RGB", (maxX, maxY), colorBG) draw = ImageDraw.Draw(img) #draw chart background draw.rectangle((offset, (offset[0]+((len(xLabels)+1)*recSize), offset[1]-((len(yLabels)+1)*recSize))), fill=colorChartBG) #draw heatmap for row in xrange(len(matrix)): for col in xrange(len(matrix[0])): pos = (offset[0]+col*recSize, offset[1]-row*recSize, offset[0]+(col+1)*recSize, offset[1]-(row+1)*recSize) fill = getColorForScope(matrix[row][col], scopes, colorChartBG) draw.rectangle(pos, fill=fill) #draw grid #x-axis for i in xrange(len(yLabels)+1): yPos = offset[1]-((i+1)*recSize) draw.line(((offset[0], yPos), (offset[0]+recSize*(len(xLabels)+1), yPos)), fill=colorGrid) #y-axis for i in xrange(len(xLabels)+1): draw.line(((offset[0]+(i+1)*recSize, offset[1]), (offset[0]+(i+1)*recSize, offset[1]-recSize*(len(yLabels)+1))), fill=colorGrid) #draw axes #x-axis draw.line((offset, (offset[0]+recSize*(len(xLabels)+1), offset[1])), fill=colorFG) for i in xrange(len(xLabels)): draw.line(((offset[0]+recSize/2+i*recSize, offset[1]-2),(offset[0]+recSize/2+i*recSize, offset[1]+2)), fill=colorFG) #y-axis draw.line((offset, (offset[0], offset[1]-recSize*(len(yLabels)+1))), fill=colorFG) for i in xrange(len(yLabels)): draw.line(((offset[0]-2, offset[1]-(recSize/2+i*recSize)),(offset[0]+2, offset[1]-(recSize/2+i*recSize))), fill=colorFG) #draw ids for i in xrange(len(yLabels)): name = yLabels[i] pos = i draw.text((margin, offset[1]-((pos+1)*recSize)), name, font=font, fill=colorFG) for i in xrange(len(xLabels)): name = xLabels[i] pos = i img.paste(rotText(name, font=font, colorBG=colorBG, colorFG=colorFG), (offset[0]+(recSize/5)+((pos)*recSize), offset[1]+2)) #clean up del draw #return heatmap chart img return img
def createChart(img, yLevel, ydist, xlabel, ylabel, header, font=ImageFont.load_default()): """Creates the chart environment and pastes the given img onto it. Returns PIL image object showing a patterngram """ #init colorBG = (255, 255, 255) colorFG = (0, 0, 0) margin = 50 #create image chartImg = Image.new("RGB", (img.size[0] + (2 * margin), img.size[1] + (2 * margin)), colorBG) #paste image to chart chartImg.paste(img, (margin + 1, margin + 1)) draw = ImageDraw.Draw(chartImg) #draw border borderY2 = img.size[1] + margin + 1 draw.rectangle(((margin, margin), (img.size[0] + margin + 1, borderY2)), outline=colorFG) #x-label labelSize = computeLabelDist(img.size[0], mode=0) for x in xrange(img.size[0]): if x % 100 == 0: s = 4 elif x % 50 == 0: s = 3 elif x % 10 == 0: s = 2 elif x % 5 == 0: s = 1 else: s = 0 #draw upper border draw.line((x + margin, margin, x + margin, margin - s), fill=colorFG) #draw lower border draw.line((x + margin, borderY2, x + margin, borderY2 + s), fill=colorFG) #draw labels if x % labelSize == 0: label = str(x) pos = (margin + x - (font.getsize(label)[0] / 2), borderY2 + 5) draw.text(pos, label, fill=colorFG, font=font) #y-label labelSize = computeLabelDist(yLevel, mode=1) for y in xrange(yLevel + 1): if y % 5 == 0: s = 3 else: s = 1 ypos = borderY2 - (y * ydist) #left border draw.line((margin - s, ypos, margin, ypos), fill=colorFG) #right border draw.line((margin + 1 + img.size[0], ypos, margin + 1 + img.size[0] + s, ypos), fill=colorFG) #draw labels if y % labelSize == 0 and y != 0: label = str(y) pos = (margin - (font.getsize(label)[0] + 4), borderY2 - (y * ydist) - (font.getsize(label)[1] / 2)) draw.text(pos, label, fill=colorFG, font=font) #===draw labels=== #xlabel draw.text((margin + (img.size[0] / 2) - (font.getsize(xlabel)[0] / 2), borderY2 + (margin / 2)), xlabel, fill=colorFG, font=font) #header draw.text((margin + (img.size[0] / 2) - (font.getsize(header)[0] / 2), margin / 2), header, fill=colorFG, font=font) #ylabel yLabelImg = rotText(ylabel, font) chartImg.paste(yLabelImg, ((margin / 2) - (yLabelImg.size[0] / 2), margin + (img.size[1] / 2) - (yLabelImg.size[1] / 2))) #clean up del yLabelImg del draw del font #return created chart image return chartImg