Editor

Python Turtle Fractal Tree

Intermediate · Fractals · 60 lines · draws in about 9 seconds

A function that draws one branch calls itself twice at the end of that branch, so every branch grows two smaller ones until the tips get leaves.

Python Turtle Fractal Tree: the finished drawing
import turtle
import random
# The same seed gives the same tree every time you run it
random.seed(7)
screen = turtle.Screen()
screen.bgcolor("honeydew")
screen.title("Fractal tree")
t = turtle.Turtle()
t.speed(10)
leaf_colors = ["forestgreen", "limegreen", "seagreen", "yellowgreen"]
def draw_branch(length, depth):
# Base case: at the tip of the smallest branch, put a leaf and stop
if depth == 0:
t.dot(15, random.choice(leaf_colors))
return
# Draw this branch: thick near the trunk, thin near the tips
t.pensize(depth * 1.5)
t.pencolor("saddlebrown")
t.forward(length)
# Recursive case: two smaller trees grow from the end of this branch,
# each bent by a slightly different angle so the tree looks natural
left_angle = random.randint(15, 30)
right_angle = random.randint(15, 30)
t.left(left_angle)
draw_branch(length * 0.75, depth - 1)
t.right(left_angle + right_angle)
draw_branch(length * 0.75, depth - 1)
# Turn back and walk down to where this branch started
t.left(right_angle)
t.penup()
t.backward(length)
t.pendown()
# The ground
t.penup()
t.goto(-140, -210)
t.pendown()
t.pensize(8)
t.pencolor("olivedrab")
t.goto(140, -210)
# Start at the bottom, pointing up, and grow the tree
t.penup()
t.goto(0, -210)
t.setheading(90)
t.pendown()
draw_branch(110, 8)
t.hideturtle()
turtle.done()

How the code works

Stop at the tips

draw_branch calls itself, so it needs a place to stop. When depth reaches 0 the turtle is at the end of a twig: it draws a leaf with dot() in a random green and returns.

# Base case: at the tip of the smallest branch, put a leaf and stop
if depth == 0:
    t.dot(15, random.choice(leaf_colors))
    return

Each branch grows two smaller trees

After drawing a branch, the turtle turns left and draws a whole smaller tree (length * 0.75, depth - 1), then turns right and draws another. Each of those does the same, so 8 levels end in 256 leaves.

# Recursive case: two smaller trees grow from the end of this branch,
# each bent by a slightly different angle so the tree looks natural
left_angle = random.randint(15, 30)
right_angle = random.randint(15, 30)
t.left(left_angle)
draw_branch(length * 0.75, depth - 1)
t.right(left_angle + right_angle)
draw_branch(length * 0.75, depth - 1)

Walk back to where the branch started

Every call must leave the turtle where it found it, facing the same way. The last turn undoes the angles, and backward(length) with the pen up returns to the bottom of the branch.

# Turn back and walk down to where this branch started
t.left(right_angle)
t.penup()
t.backward(length)
t.pendown()

Plant the tree

The trunk starts near the bottom of the screen, and setheading(90) points the turtle up. draw_branch(110, 8) starts with a trunk 110 long, and each level of branches is three quarters as long as the one below.

# Start at the bottom, pointing up, and grow the tree
t.penup()
t.goto(0, -210)
t.setheading(90)
t.pendown()
draw_branch(110, 8)

Make it yours

Change the code above and press Run. Some ideas:

  • Change random.seed(7) to random.seed(1) or any other number to grow a different tree.
  • Change leaf_colors to ["pink", "hotpink", "white"] for a tree in blossom.
  • Change draw_branch(110, 8) to draw_branch(110, 6) for a simpler tree with 64 leaves.

What it uses

Every turtle command the site supports is listed on Python turtle online.