To draw letters with Python Turtle, move the turtle between the corner points of each letter with goto(), lifting the pen with penup() between strokes. This guide starts with one letter, then builds a small reusable “stroke font” for all 26 capital letters, so you can draw any word, centre it, colour it, and compare the result with write().
Every program was run with Python 3.12.5 (Tk 8.6) on Windows 11; the screenshots are the real Turtle windows. For the full reference, see the turtle module reference.
Draw a single letter: A
A letter is just a few straight lines. For A, draw the two slanted sides in one stroke, then lift the pen and draw the crossbar:
import turtle
screen = turtle.Screen()
screen.setup(500, 400)
screen.title("Letter A")
t = turtle.Turtle()
t.pensize(8)
t.color("#306998")
# the two slanted sides
t.penup()
t.goto(-60, -100)
t.pendown()
t.goto(0, 100)
t.goto(60, -100)
# the crossbar
t.penup()
t.goto(-36, -20)
t.pendown()
t.goto(36, -20)
t.hideturtle()
turtle.done()
Using goto() with coordinates is easier than working out angles for left() and right(): you only need to know where each corner is.
Plan letters on a grid
To draw many letters that match, give every letter the same box. Here each letter sits on a grid 4 units wide and 6 units tall, and a letter is a list of strokes, each a list of grid points. This is A with its points labelled:
import turtle
from turtle_letters import LETTERS
screen = turtle.Screen()
screen.setup(520, 560)
screen.title("Letter A on a 4 x 6 grid")
S = 60 # pixels per grid unit
X0, Y0 = -120, -200 # bottom-left corner of the grid
t = turtle.Turtle()
t.hideturtle()
t.speed(0)
t.color("#cfd8e3") # light grid
for i in range(5):
t.penup(); t.goto(X0 + i * S, Y0); t.pendown(); t.goto(X0 + i * S, Y0 + 6 * S)
for j in range(7):
t.penup(); t.goto(X0, Y0 + j * S); t.pendown(); t.goto(X0 + 4 * S, Y0 + j * S)
t.color("#306998") # the letter
t.pensize(8)
for stroke in LETTERS["A"]:
t.penup(); t.goto(X0 + stroke[0][0] * S, Y0 + stroke[0][1] * S); t.pendown()
for x, y in stroke[1:]:
t.goto(X0 + x * S, Y0 + y * S)
t.penup() # label the points
for stroke in LETTERS["A"]:
for x, y in stroke:
t.goto(X0 + x * S, Y0 + y * S)
t.dot(14, "#c62828")
left = x == 0 # labels on the left side go outside the letter
t.goto(X0 + x * S + (-12 if left else 12), Y0 + y * S + 6)
t.color("#c62828")
t.write(f"({x}, {y})", align="right" if left else "left", font=("Arial", 12, "bold"))
turtle.done()
Because the points are in grid units, the same data can be drawn at any size: multiply each point by size / 6 and add the position of the letter.
A reusable A–Z letter module
Save this file as turtle_letters.py next to your programs. It holds the strokes for all 26 capital letters and three functions: draw_letter() for one letter, draw_text() for a word, and text_width() to measure a word before you draw it:
"""A tiny stroke font for Python Turtle: capital letters A-Z drawn with straight lines."""
# Each letter is a list of strokes. A stroke is a list of (x, y) points on a grid
# 4 units wide and 6 units tall; the pen goes down at the first point of each stroke.
LETTERS = {
"A": [[(0, 0), (0, 4), (2, 6), (4, 4), (4, 0)], [(0, 3), (4, 3)]],
"B": [[(0, 0), (0, 6), (3, 6), (4, 5), (4, 4), (3, 3), (0, 3)], [(3, 3), (4, 2), (4, 1), (3, 0), (0, 0)]],
"C": [[(4, 6), (1, 6), (0, 5), (0, 1), (1, 0), (4, 0)]],
"D": [[(0, 0), (0, 6), (2, 6), (4, 4), (4, 2), (2, 0), (0, 0)]],
"E": [[(4, 6), (0, 6), (0, 0), (4, 0)], [(0, 3), (3, 3)]],
"F": [[(4, 6), (0, 6), (0, 0)], [(0, 3), (3, 3)]],
"G": [[(4, 5), (3, 6), (1, 6), (0, 5), (0, 1), (1, 0), (3, 0), (4, 1), (4, 3), (2, 3)]],
"H": [[(0, 0), (0, 6)], [(4, 0), (4, 6)], [(0, 3), (4, 3)]],
"I": [[(1, 6), (3, 6)], [(2, 6), (2, 0)], [(1, 0), (3, 0)]],
"J": [[(1, 6), (4, 6)], [(3, 6), (3, 1), (2, 0), (1, 0), (0, 1)]],
"K": [[(0, 0), (0, 6)], [(4, 6), (0, 2)], [(1, 3), (4, 0)]],
"L": [[(0, 6), (0, 0), (4, 0)]],
"M": [[(0, 0), (0, 6), (2, 3), (4, 6), (4, 0)]],
"N": [[(0, 0), (0, 6), (4, 0), (4, 6)]],
"O": [[(1, 0), (0, 1), (0, 5), (1, 6), (3, 6), (4, 5), (4, 1), (3, 0), (1, 0)]],
"P": [[(0, 0), (0, 6), (3, 6), (4, 5), (4, 4), (3, 3), (0, 3)]],
"Q": [[(1, 0), (0, 1), (0, 5), (1, 6), (3, 6), (4, 5), (4, 1), (3, 0), (1, 0)], [(2, 2), (4, 0)]],
"R": [[(0, 0), (0, 6), (3, 6), (4, 5), (4, 4), (3, 3), (0, 3)], [(2, 3), (4, 0)]],
"S": [[(4, 5), (3, 6), (1, 6), (0, 5), (0, 4), (1, 3), (3, 3), (4, 2), (4, 1), (3, 0), (1, 0), (0, 1)]],
"T": [[(0, 6), (4, 6)], [(2, 6), (2, 0)]],
"U": [[(0, 6), (0, 1), (1, 0), (3, 0), (4, 1), (4, 6)]],
"V": [[(0, 6), (2, 0), (4, 6)]],
"W": [[(0, 6), (1, 0), (2, 4), (3, 0), (4, 6)]],
"X": [[(0, 6), (4, 0)], [(4, 6), (0, 0)]],
"Y": [[(0, 6), (2, 3), (4, 6)], [(2, 3), (2, 0)]],
"Z": [[(0, 6), (4, 6), (0, 0), (4, 0)]],
" ": [],
}
WIDTH, HEIGHT = 4, 6
def draw_letter(t, letter, x, y, size=60):
"""Draw one letter with its bottom-left corner at (x, y). size = letter height."""
scale = size / HEIGHT
for stroke in LETTERS.get(letter.upper(), []):
t.penup()
t.goto(x + stroke[0][0] * scale, y + stroke[0][1] * scale)
t.pendown()
for px, py in stroke[1:]:
t.goto(x + px * scale, y + py * scale)
t.penup()
def text_width(text, size=60, spacing=1.5):
"""Width of a word in pixels, so you can centre it."""
scale = size / HEIGHT
return len(text) * (WIDTH + spacing) * scale - spacing * scale
def draw_text(t, text, x, y, size=60, spacing=1.5):
"""Draw a word left to right. Returns the x position after the last letter."""
step = (WIDTH + spacing) * size / HEIGHT
for letter in text:
draw_letter(t, letter, x, y, size)
x += step
return x
Lowercase input is converted with upper(), and characters that are not in LETTERS are skipped (they leave a gap), so the functions never crash on unexpected text.
Draw the whole alphabet
import turtle
from turtle_letters import draw_text, text_width
screen = turtle.Screen()
screen.setup(900, 420)
screen.title("Turtle letters A to Z")
t = turtle.Turtle()
t.hideturtle()
t.speed(0)
t.pensize(4)
t.color("#306998")
for row, y in [("ABCDEFGHIJKLM", 50), ("NOPQRSTUVWXYZ", -110)]:
draw_text(t, row, -text_width(row, 64) / 2, y, size=64)
turtle.done()
Draw a word and centre it
text_width() tells you how wide a word will be, so starting at -text_width(word, size) / 2 centres it. Changing the pen colour between letters gives each letter its own colour:
import turtle
from turtle_letters import draw_text, text_width
screen = turtle.Screen()
screen.setup(820, 400)
screen.bgcolor("#0a1b2e")
screen.title("PYTHON")
t = turtle.Turtle()
t.hideturtle()
t.speed(0)
t.pensize(10)
word = "PYTHON"
size = 120
colors = ["#e53935", "#fb8c00", "#fdd835", "#43a047", "#1e88e5", "#8e24aa"]
x = -text_width(word, size) / 2 # start here to centre the word
for i, letter in enumerate(word):
t.color(colors[i % len(colors)])
x = draw_text(t, letter, x, -size / 2, size)
turtle.done()
You can check the widths directly:
from turtle_letters import text_width
for word in ["A", "HI", "PYTHON"]:
print(f"{word:7} {text_width(word, size=60):6.1f} px")
Output:
A 40.0 px
HI 95.0 px
PYTHON 315.0 px
Draw your name with a shadow
Drawing the same text twice, first slightly offset in grey, gives a simple shadow. To ask for the name when the program runs, use screen.textinput() as shown in the comment:
import turtle
from turtle_letters import draw_text, text_width
screen = turtle.Screen()
screen.setup(820, 420)
screen.title("Your name")
t = turtle.Turtle()
t.hideturtle()
t.speed(0)
name = "EMMA ROSE" # or: screen.textinput("Name", "Type your name").upper()
size = 80
# shadow first, then the letters on top
for dx, dy, color, width in [(5, -5, "#b0bec5", 9), (0, 0, "#c2185b", 9)]:
t.pensize(width)
t.color(color)
draw_text(t, name, -text_width(name, size) / 2 + dx, -size / 2 + dy, size)
turtle.done()
Curved letters with circle()
Straight lines are easiest, but circle() can draw round letters. circle(r, extent) draws part of a circle, and a negative radius goes clockwise (see the Python Turtle cheat sheet for all circle() options):
import turtle
screen = turtle.Screen()
screen.setup(780, 360)
screen.title("Curved letters with circle()")
t = turtle.Turtle()
t.hideturtle()
t.speed(0)
t.pensize(8)
t.color("#2e7d32")
def jump(x, y, heading=0):
t.penup()
t.goto(x, y)
t.setheading(heading)
t.pendown()
def draw_O(x, y, size):
jump(x + size / 2, y) # bottom of the circle
t.circle(size / 2)
def draw_C(x, y, size):
r = size / 2
jump(x + r + r * 0.707, y + r + r * 0.707, 135) # start at the top right
t.circle(r, 270) # leave the right side open
def draw_D(x, y, size):
jump(x, y, 90)
t.forward(size) # straight back
t.setheading(0)
t.circle(-size / 2, 180) # clockwise half circle back down
def draw_S(x, y, size):
r = size / 4
jump(x + 2 * r, y + 3 * r, 90)
t.circle(r, 270) # top curve, counterclockwise
t.circle(-r, 270) # bottom curve, clockwise
for draw, x in [(draw_C, -300), (draw_O, -130), (draw_D, 40), (draw_S, 175)]:
draw(x, -60, 120)
turtle.done()
Drawn letters vs write()
If you only need to show text, write() is simpler: it uses a real font. Draw letters yourself when you want to animate them, style every line, or control each stroke. More on fonts in Python Turtle font.
import turtle
from turtle_letters import draw_text
screen = turtle.Screen()
screen.setup(760, 360)
screen.title("Drawn letters vs write()")
t = turtle.Turtle()
t.hideturtle()
t.speed(0)
t.pensize(6)
t.color("#306998")
draw_text(t, "HI", -300, -40, size=100) # drawn with lines
t.goto(170, -40)
t.color("#c62828")
t.write("HI", align="center", font=("Arial", 80, "bold")) # a font
t.color("#5b6b7b")
for x, label in [(-240, "draw_text()"), (170, "write()")]:
t.goto(x, -110)
t.write(label, align="center", font=("Consolas", 16, "normal"))
turtle.done()
Drawing letters (goto()) | write() | |
|---|---|---|
| Looks like | Lines you control | Any installed font |
| Animated drawing | Yes: the turtle draws each stroke | No: text appears at once |
| Pen size, colour per stroke | Yes | One colour per call |
| Code needed | Letter data + a function | One line |
| Lowercase, accents, symbols | Only what you define | Everything in the font |
Tips
- Watch it draw: use
t.speed(3)instead ofspeed(0)to see each stroke, which is great for classes. - Draw instantly: for long sentences add
screen.tracer(0)before drawing andscreen.update()after. - Add a letter: add a key to
LETTERSwith its strokes on the 4 × 6 grid, e.g."!": [[(2, 6), (2, 2)], [(2, 0.5), (2, 0)]]. - Rounded look: a thick pen already rounds the line ends;
t.pensize(12)makes the font look bold.
Frequently asked questions
How do you draw letters in Python Turtle?
Move the turtle between the letter’s corner points with goto(), and use penup()/pendown() between separate strokes. Storing the points of each letter in a dictionary lets one function draw any letter.
How do I write text instead of drawing it?
Use t.write("Hello", font=("Arial", 24, "bold")). It is quicker, but the text appears at once instead of being drawn.
How do I draw a whole word or my name with Turtle?
Draw the letters one after another, moving the start x by the letter width plus a gap each time, as draw_text() does in this guide.
How do I centre a word in the Turtle window?
Measure the word first, then start at minus half its width. With the module above: draw_text(t, word, -text_width(word, size) / 2, y, size).
Can Turtle draw lowercase letters?
Yes, if you add their strokes to the dictionary. The module in this guide converts text to capitals, so lowercase input still works.
Try these Turtle drawing tutorials next:
Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn