Lines

Let's start simply to get warmed up.  This will draw a square that is 25 pixels on a side.

Download: file
import board
from adafruit_turtle import Color, turtle

turtle = turtle(board.DISPLAY)
print("Turtle time! Lets draw a simple square")

turtle.pencolor(Color.WHITE)
turtle.pendown()

for _ in range(4):
    turtle.forward(25)
    turtle.left(90)

while True:
    pass

Dots

Next, put a 8 pixel radius dot at each corner. Remember that dot() doesn't effect the turtle's position or heading, so dots can be easily added to an existing script.

Download: file
import board
from adafruit_turtle import turtle, Color

print("Turtle time! Lets draw a square with dots")

turtle = turtle(board.DISPLAY)
turtle.pendown()

for _ in range(4):
    turtle.dot(8)
    turtle.left(90)
    turtle.forward(25)

while True:
    pass 

Circles

Circles are a little tricker since the outline starts with the initial turtle position and heading. The nice thing is that the turtle ends up where it started, and with the same heading. The code below moves the turtle to near the right side of the screen and then points it to the left. It then draws 6 circles in different colors, moving left between each. By moving by the diameter we use, the circles don't overlap.

Download: file
import board
from adafruit_turtle import Color, turtle

turtle = turtle(board.DISPLAY)

mycolors = [Color.WHITE, Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE, Color.PURPLE]
turtle.penup()
turtle.forward(130)
turtle.right(180)
turtle.pendown()

for i in range(6):
    turtle.pencolor(mycolors[i])
    turtle.circle(25)
    turtle.penup()
    turtle.forward(50)
    turtle.pendown()

while True:
    pass

To have them overlap, reduce how far the turtle moves between each one.

Scaling to the Screen

Since adafruit_turtle can be used on boards with different sized screens, it can be a good idea to scale drawings to fit on the screen. The library will clip drawings to the screen so if you draw off the edge your script won't crash, but the result might not look great. The script below shows an approach to scaling to the screen. It also shows how to detect that the turtle is back where it started, accounting for some rounding error.

Download: file
import board
from adafruit_turtle import Color, turtle

turtle = turtle(board.DISPLAY)
starsize = min(board.DISPLAY.width, board.DISPLAY.height) * 0.9  # 90% of screensize

print("Turtle time! Lets draw a star")

turtle.pencolor(Color.BLUE)

turtle.penup()
turtle.goto(-starsize/2, 0)
turtle.pendown()

start = turtle.pos()
while True:
    turtle.forward(starsize)
    turtle.left(170)
    if abs(turtle.pos() - start) < 1:
        break

while True:
    pass

Using Color

Changing color as you draw can produce startling results, as these scripts show:

Download: file
import board
from adafruit_turtle import Color, turtle

turtle = turtle(board.DISPLAY)
benzsize = min(board.DISPLAY.width, board.DISPLAY.height) * 0.5

print("Turtle time! Lets draw a rainbow benzene")

colors = (Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.PURPLE)

turtle.pendown()
start = turtle.pos()

for x in range(benzsize):
    turtle.pencolor(colors[x%6])
    turtle.forward(x)
    turtle.left(59)

while True:
    pass
Download: file
import board
from adafruit_turtle import turtle, Color

turtle = turtle(board.DISPLAY)


turtle.pendown()

colors = [Color.ORANGE, Color.PURPLE]

for x in range(400):
    turtle.pencolor(colors[x % 2])
    turtle.forward(x)
    turtle.left(91)

while True:
    pass

Using circle for Polygons

Below is a design and script to make it using just lines and turns.

Download: file
import board
from adafruit_turtle import turtle

turtle = turtle(board.DISPLAY)


# turtle.penup()
# turtle.right(45)
# turtle.forward(90)
# turtle.right(75)

turtle.pendown()
for _ in range(21):
    for _ in range(6):
        turtle.forward(50)
        turtle.right(61)
    turtle.right(11.1111)

while True:
    pass

You can do something very similar using circles and the step parameter, though you may need to tweak some things since you're dealing with the radius instead of side length. This results is quite a bit less code. The following image and script show this.

Download: file
import board
from adafruit_turtle import turtle

turtle = turtle(board.DISPLAY)

turtle.pendown()
for _ in range(32):
    turtle.circle(50, steps=6)
    turtle.right(11.1111)

while True:
    pass

Fractals

Turtle graphics are quite handy for drawing fractals.

The first example is a hilbert curve.

Download: file
import board
from adafruit_turtle import turtle

def hilbert2(step, rule, angle, depth, t):
    if depth > 0:
        a = lambda: hilbert2(step, "a", angle, depth - 1, t)
        b = lambda: hilbert2(step, "b", angle, depth - 1, t)
        left = lambda: t.left(angle)
        right = lambda: t.right(angle)
        forward = lambda: t.forward(step)
        if rule == "a":
            left(); b(); forward(); right(); a(); forward(); a(); right(); forward(); b(); left()
        if rule == "b":
            right(); a(); forward(); left(); b(); forward(); b(); left(); forward(); a(); right()

turtle = turtle(board.DISPLAY)
turtle.penup()

turtle.goto(-80, -80)
turtle.pendown()
hilbert2(5, "a", 90, 5, turtle)

while True:
    pass

Another interesting fractal is the Sierpinski triangle, shown below.

Download: file
import board
from adafruit_turtle import turtle

def getMid(p1,p2):
    return ( (p1[0]+p2[0]) / 2, (p1[1] + p2[1]) / 2) #find midpoint

def triangle(points, depth):

    turtle.penup()
    turtle.goto(points[0][0], points[0][1])
    turtle.pendown()
    turtle.goto(points[1][0], points[1][1])
    turtle.goto(points[2][0], points[2][1])
    turtle.goto(points[0][0], points[0][1])

    if depth > 0:
        triangle([points[0],
                  getMid(points[0], points[1]),
                  getMid(points[0], points[2])],
                 depth-1)
        triangle([points[1],
                  getMid(points[0], points[1]),
                  getMid(points[1], points[2])],
                 depth-1)
        triangle([points[2],
                  getMid(points[2], points[1]),
                  getMid(points[0], points[2])],
                 depth-1)

turtle = turtle(board.DISPLAY)
big = min(board.DISPLAY.width / 2, board.DISPLAY.height / 2)
little = big / 1.4
seed_points = [[-big, -little],[0,big],[big,-little]] #size of triangle
triangle(seed_points,4)

while True:
    pass

The final example is a Koch snowflake. On the small displays we can get 4 generations before rounding errors start messing things up too much. Even so, it's a nice design. See below.

Download: file
import board
from adafruit_turtle import turtle

def f(side_length, depth, generation):
    if depth == 0:
        side = turtle.forward(side_length)
    else:
        side = lambda: f(side_length / 3, depth - 1, generation + 1)
        side()
        turtle.left(60)
        side()
        turtle.right(120)
        side()
        turtle.left(60)
        side()

turtle = turtle(board.DISPLAY)

unit= min(board.DISPLAY.width / 3, board.DISPLAY.height / 4)
top_len = unit * 3
print(top_len)
turtle.penup()
turtle.goto(-1.5 * unit, unit)
turtle.pendown()

num_generations = 3
top_side = lambda: f(top_len, num_generations, 0)

top_side()
turtle.right(120)
top_side()
turtle.right(120)
top_side()

while True:
    pass

The script below is much the same, but overlays 3 generations in different colors. Beyond 3, rounding causes subsequent generations to not line up.

Download: file
import board
from adafruit_turtle import turtle, Color

generation_colors = [Color.RED, Color.BLUE, Color.GREEN]

def f(side_length, depth, generation):
    if depth == 0:
        side = turtle.forward(side_length)
    else:
        side = lambda: f(side_length / 3, depth - 1, generation + 1)
        side()
        turtle.left(60)
        side()
        turtle.right(120)
        side()
        turtle.left(60)
        side()

def snowflake(num_generations, generation_color):
    top_side = lambda: f(top_len, num_generations, 0)
    turtle.pencolor(generation_color)
    top_side()
    turtle.right(120)
    top_side()
    turtle.right(120)
    top_side()


turtle = turtle(board.DISPLAY)

unit= min(board.DISPLAY.width / 3, board.DISPLAY.height / 4)
top_len = unit * 3
print(top_len)
turtle.penup()
turtle.goto(-1.5 * unit, unit)
turtle.pendown()

for generations in range(3):
    snowflake(generations, generation_colors[generations])
    turtle.right(120)

while True:
    pass

Where to Find More

You can find much more information about turtle graphics as well as example scripts through an Internet search of "turtle python graphics examples" or some variation. Since turtle graphics are mainly in terms of moving and turning they can usually be converted to CircuitPython and the adafruit_turtle library.

Check out these example sites:

This guide was first published on Jul 03, 2019. It was last updated on Jul 03, 2019.
This page (Example Scripts) was last updated on Oct 24, 2020.