DrawBot is a powerful, free application for MacOSX that invites you to write simple Python scripts to generate two-dimensional graphics.” drawbot.com
In Spring 2020, I took Ben Kiel’s Programming Design class and finally explored the intersections of coding and design. I’m a Computer Science minor, and since taking CSE 131 (Intro to CS), I’ve been linking for ways to make fun stuff with code. I’ve found DrawBot to be the perfect tool. I made a bunch of explorations and had a lot of fun, and a lot of help from Ben Kiel and my friends Grace Park and Jefferson Duan. I was really glad I minored in Computer Science, because a ton of concepts I learned in CSE 131 (Intro to CS) came in handy. Since I learned Java in that class, transitioning to Python was more or less seamless.
The following is a series of projects I made in Programming Design. I’ve included a snippet of each project’s code, but I’ll warn you that it’s not the most clean or efficient code out there. Still works, though!
January 2020
I used DrawBot to create patterns via iterating through the canvas’ width and height. In line with my obsession with honeycomb configurations, many of these patterns create hexagons in one way or another. One version allows the user to pick the colors of the different shapes that make up the pattern.
def pattern():
    for i, x in enumerate(width):
        for y in height:
            if i%2 == 0: #if even
                y = y+(module)/2
            image = module - padding
            diff = padding/2
            fill(0, 0, 0, 1)
            drawHex1(x+diff+9, y-diff*2, image, image)
            fill(random(), random(), 0.7, 0.9)
            drawHex2(x+diff+9, y-diff*2, image, image)
            fill(random(), random(), 0.7, 0.9)
            drawHex3(x+diff+9, y-diff*2, image, image)
            stroke(0, 0, 0, 1)

Sonic Poster
February 2020
I made this poster in collaboration with Grace Park, Jefferson Duan, and Joseph Wang. The code iterates through a list of the letters “Alone on a Friday night? God, you’re pathetic” (we are funny. Or cringey). Each letter takes its color from the corresponding pixel at that location, using DrawBot’s imagePixelColor() method. We were fortunate to print this on WashU’s new risograph printers! February 2020

theLine = ["A","L","O","N","E","O","N","A","F","R","I","D","A","Y","N","I","G","H","T","?","G","O","D","Y","O","U","R","E","P","A","T","H","E","T","I","C"]
i = 0
for y in range(0, height, s):
    for x in range(0, width, s):
        color = imagePixelColor(path, (x, y))
        if color:
            r, g, b, a = color
            # set the color
            fill(r, g, b, a)
            # draw some text
            text(theLine[i], (x, y))
        i += 1
        if (i >= len(theLine)):
            i = 0
Halloween Candy Tournament
April 2020
This takes data (in a .CSV) from FiveThirtyEight’s Ultimate Halloween Candy Power Ranking. I wanted to mimic the tournament sorter they used to collect preferences from thousands of individuals. The colors are 100% randomly generated using the random() method to determine each RGB value. Cool, right?
The code for this is uh… long, so here’s the part where it parses the .CSV file. It then takes this data, picks two candies, and shows each candy’s stats on their respective sides.
candies = {}
with open("candy-data.csv", newline='', encoding="utf-8") as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        candies[row["competitorname"]] = (row["winpercent"], row["chocolate"], row["fruity"], row["rank"], row["peanutyalmondy"], row["money"], row["crispedricewafer"], row["hard"])
SQSH Background Generator
April 2020
I created an easy-to-use programmed background generator for SQSH PR materials.  SQSH, or St. Louis Queer+ Support Helpline, “offers free, confidential, and identity-affirming emotional support and resource referrals, by and for the St. Louis LGBTQIA+ community.” Read more about that here!
The Avatar’s Love
Fall 2020
A short motion sequence for part of the song “The Avatar’s Love” from Avatar: The Last Airbender. This is a sequence of images selected from a set of 108 I made in under two weeks using all sorts of media including ink, watercolor, ginkgo leaves, a flatbed scanner (highly recommend), Illustrator, Photoshop, and DrawBot. It was also my first time using After Effects.
Something I love about programming is the random function. This is used in games (you’ll often hear the term RNG, random number generated) to introduce unpredictability. It’s called Math.random() in Java and random() in Python, and it’s useful for visual exploration. When I first started using DrawBot, I experimented a lot with placing text (and images) on random parts of the canvas using random(). It’s fascinating to see where things end up! Some placements seem too good to be true.
fill(random(), random(), 0.2, 0.9)
rect(random()*inch(6), random()*inch(4.5), random()*inch(10), random()*inch(10))
fill(0.4, random(), 0.6, 0.9)
rect(random()*inch(6), random()*inch(4.5), random()*inch(6), random()*inch(6))
fill(random(), random(), 0.6, 0.8)
rect(random()*inch(6), random()*inch(4.5), random()*inch(6), random()*inch(10))
fill(random(), random(), 0.6, 0.8)
rect(random()*inch(6), random()*inch(4.5), random()*inch(3), random()*inch(9))

I can treat DrawBot as a stepping stone. No matter what it produces, I can leave it be or I can tweak it. I used DrawBot to quickly generate compositions with random shapes for a different project. I then lightly edited the images in Illustrator.
My final video includes several frames made with combining these Drawbot-generated images with other textures.
Pink in the Night
Winter 2021
I’ve also used random() in DrawBot with text.
fontList = installedFonts()
for fontSelection in fontList:

    if “IBMPlexMono” in fontSelection:
        fill(random(), random(), 0.4, 0.9)
        text(“pathetic”, (random()*800, random()*1000))

Continuing my random() experimentation, I used song lyrics as the input. The cool thing about words is that they mean different things in different contexts. Putting lyrics through DrawBot not only transforms their meaning but visualizes them. Mitski’s “Pink in the Night” lyrics hit different when randomly placed.
Repeated lyrics like “I hear my heart breaking tonight,” “I could stare at your back all day,” “I love you,” “try again,” and “and again,” form over and over in different ways. The code uses methods inside methods. lyrics(line) randomly places line somewhere on the canvas. canitryagain2() then applies lyrics() to the lines “can i,” “try again,” and “and again.”
def lyrics(line):
    fill(0.9, random(), random(), 0.9)
    text(line, (random()*1000, random()*1000))
def canitryagain2():
    lyrics("can i")
    lyrics("try again")
    lyrics("try again")
    lyrics("try again")
    lyrics("and again")
    lyrics("and again")
    lyrics("and again")
    lyrics("and again")
    lyrics("and again")
    lyrics("and again")
Mentorship provided by Ben Kiel
Inspiration from Andy Clymer and Agyei Archer
Data provided by FiveThirtyEight
Lyrics written by Mitski
Hatch designed by Mark Caneso from ps Type. I love how funky its shapes are!
IBM Plex Mono designed by Mike Abbink, IBM BX&D, in collaboration with Bold Monday. I love that a monospace typeface has so many weights. I’ve developed a deep appreciation not only for Plex’s letterforms but also that IBM very intentionally made Plex open source! Do I use IBM Plex Mono too much? Let me know in an email!

Want more?

Back to Top