analytics

Monday, September 29, 2014

spiral chart

A program I wrote takes some values like:
[3,5,2,8,1,3,7]
first sorts greatest to smallest:
[8,7,5,3,3,2,1] (The program works whether they are sorted or not)
Then makes a spiral with the area of each rectangle corresponding to the values in this list... it doesn't write the numbers on them but I've labeled them:
I had intended it as a good way to show the relative sizes of elements of a dataset, but it doesn't really work for that as well as I thought it would because I think people aren't as good at recognizing rectangular areas and there's some optical illusions.
For example:
[1,1,1,1,1,1,1]
I had to actually measure these to verify they all have the same area so that precludes it from being a good tool for data representation. It's kind of an interesting optical illusion though.
The way I wrote the program you can put any size in for the main rectangle here is the all 1's again but in 800x350
There can be any number of data points here is 14 following the Fibonacci series:
This one is a 1920x1080 for a desktop background of the numbers 1,2,3,...13,14

I'm kind of proud of this source code, it took some thinking to make the program this short...

*Python Source Code**
import Image, ImageDraw
def rsum(data, i):
    sum = 0
    if i+1 < len(data):
        for d in range(i, len(data)):
            sum+=data[d][0]
        return sum
    else:
        return data[len(data)-1][0]
def parserec(coords):
    leastx = coords[0][0]
    leasty = coords[0][1]
    mostx = coords[0][0]
    mosty = coords[0][1]
    for i in range(1, len(coords)):
        if coords[i][0] < leastx:
            leastx = coords[i][0]
        if coords[i][0] > mostx:
            mostx = coords[i][0]
        if coords[i][1] < leasty:
            leasty = coords[i][1]
        if coords[i][1] > mosty:
            mosty = coords[i][1]
    return [(leastx, leasty), (mostx, mosty)]
def main():
    size = [800,800]
    pic = Image.new("RGB", size)
    draw = ImageDraw.Draw(pic)
    data = [[1, (255,255,0), "widgets"],[1,(255,0,0), "thingies"],[1,(0,255,0),"stuff"],[1,(0,0,255),"foo"], [1,(0,255,255),"bar"], [1,(125,125,255),"bar2"],[1,(125,125,0),"bar3"]]
    r = rsum(data,0)
    data = list(reversed(sorted(data)))
    rects = [[(0,1),(0,0),(size[0],0),(size[0],1)], [(size[0]-1,1),(size[0],1),(size[0],size[1]),(size[0]-1,size[1])],[(size[0]-1, size[1]-1), (size[0]-1, size[1]), (0,size[1]), (0, size[1]-1)],[(1,size[1]-1), (0, size[1]-1), (0, 1), (1, 1)]]
    for i in range(0, len(data)):
        thisrect = i+4
        width = data[i][0]*1.0/rsum(data, i)
        x0 = rects[thisrect-1][3][0]+width*(rects[thisrect-1][0][0]-rects[thisrect-1][3][0])
        y0 = rects[thisrect-1][3][1]+width*(rects[thisrect-1][0][1]-rects[thisrect-1][3][1])
        x1 = rects[thisrect-1][3][0]
        y1 = rects[thisrect-1][3][1]
        x2 = rects[thisrect-3][0][0]
        y2 = rects[thisrect-3][0][1]
        x3 = (x0-x1)+x2
        y3 = (y0-y1)+y2
        coords = [(x0,y0),(x1,y1),(x2,y2), (x3,y3)]
        rects.append(coords)
        coordstlbr = parserec(coords)
        draw.rectangle(coordstlbr, fill=data[i][1])
    pic.save("spiralgraph.png")
main()

No comments:

Post a Comment