Python’s turtle module provides a classic pen-plotter-style drawing canvas built on Tkinter — move a turtle across the screen, pen down to draw, pen up to move without drawing. import turtle. Move: turtle.forward(100), turtle.backward(50), turtle.right(90), turtle.left(45). Position: turtle.goto(x, y), turtle.home() (reset to origin), turtle.pos() → (x, y). Pen: turtle.penup() / turtle.pendown(); turtle.pencolor("red") or turtle.pencolor(0.5, 0.2, 0.8) (RGB 0–1); turtle.pensize(3). Fill: turtle.fillcolor("blue") → turtle.begin_fill() → draw shape → turtle.end_fill(). Shapes: turtle.circle(radius, extent=None, steps=None) — full circle or arc or polygon. Speed: turtle.speed(0) — fastest (no animation); turtle.tracer(0) + turtle.update() — batch mode for complex drawings. Screen: turtle.Screen().setup(800, 600), turtle.bgcolor("white"), turtle.done(). Multi-turtle: t1 = turtle.Turtle(). Claude Code generates fractal visualizations, algorithmic art, educational interactive demos, and geometry explorers.
CLAUDE.md for turtle
## turtle Stack
- Stdlib: import turtle
- Move: turtle.forward(d); turtle.right(a); turtle.goto(x, y)
- Pen: turtle.penup(); turtle.pendown(); turtle.pencolor("red"); turtle.pensize(2)
- Fill: turtle.fillcolor("blue"); turtle.begin_fill(); ...; turtle.end_fill()
- Shape: turtle.circle(r) # r<0 draws clockwise
- Speed: turtle.tracer(0); turtle.update() # batch mode (fast)
- End: turtle.done() # enter Tk event loop (keep window open)
- Note: requires a display; use turtle.Screen().setup() for headless testing
turtle Drawing Pipeline
# app/turtleutil.py — shapes, fractals, spirograph, text, multi-turtle
from __future__ import annotations
import math
import turtle
from contextlib import contextmanager
from dataclasses import dataclass
from typing import Callable
# ─────────────────────────────────────────────────────────────────────────────
# 1. Drawing context helpers
# ─────────────────────────────────────────────────────────────────────────────
@contextmanager
def batch_draw(t: "turtle.Turtle | None" = None):
"""
Context manager that disables animation, runs the drawing, then updates
once. Dramatically speeds up complex drawings.
Example:
with batch_draw():
draw_spiral(100)
"""
screen = turtle.Screen()
screen.tracer(0)
try:
yield t or turtle.getturtle()
finally:
screen.update()
@contextmanager
def filled(t: "turtle.Turtle", color: str = "blue"):
"""
Context manager that fills a closed shape drawn in the block.
Example:
t = turtle.Turtle()
with filled(t, "gold"):
for _ in range(6):
t.forward(80)
t.left(60)
"""
t.fillcolor(color)
t.begin_fill()
try:
yield t
finally:
t.end_fill()
def setup_screen(
width: int = 800,
height: int = 600,
bg: str = "white",
title: str = "turtle",
) -> turtle.Screen:
"""
Configure and return the turtle screen.
Example:
screen = setup_screen(1000, 700, bg="black", title="My Drawing")
"""
screen = turtle.Screen()
screen.setup(width, height)
screen.bgcolor(bg)
screen.title(title)
return screen
def new_turtle(
color: str = "black",
pensize: int = 1,
speed: int = 0,
hide: bool = True,
) -> turtle.Turtle:
"""
Create and configure a new Turtle instance.
Example:
t = new_turtle(color="red", pensize=2)
"""
t = turtle.Turtle()
t.pencolor(color)
t.pensize(pensize)
t.speed(speed)
if hide:
t.hideturtle()
return t
# ─────────────────────────────────────────────────────────────────────────────
# 2. Basic geometric shapes
# ─────────────────────────────────────────────────────────────────────────────
def draw_polygon(
t: turtle.Turtle,
sides: int,
length: float,
fill_color: "str | None" = None,
) -> None:
"""
Draw a regular polygon with given number of sides and side length.
Example:
t = new_turtle()
draw_polygon(t, 6, 60, fill_color="yellow") # hexagon
"""
if fill_color:
t.fillcolor(fill_color)
t.begin_fill()
angle = 360.0 / sides
for _ in range(sides):
t.forward(length)
t.left(angle)
if fill_color:
t.end_fill()
def draw_star(
t: turtle.Turtle,
size: float,
points: int = 5,
fill_color: "str | None" = None,
) -> None:
"""
Draw a star with given number of points.
Example:
t = new_turtle(color="red")
draw_star(t, 80, points=5, fill_color="gold")
"""
if fill_color:
t.fillcolor(fill_color)
t.begin_fill()
angle = 180 - (180 * (points - 2) / points)
for _ in range(points):
t.forward(size)
t.right(180 - angle)
t.forward(size)
t.right(72 + angle - (180 - angle))
# Simple star: use angle 144 for 5-point star
# Reset and use the simpler approach
t.penup()
if fill_color:
t.end_fill()
def draw_star_simple(
t: turtle.Turtle,
size: float,
fill_color: "str | None" = None,
) -> None:
"""
Draw a 5-pointed star (always works).
Example:
draw_star_simple(t, 100, fill_color="gold")
"""
if fill_color:
t.fillcolor(fill_color)
t.begin_fill()
for _ in range(5):
t.forward(size)
t.right(144)
if fill_color:
t.end_fill()
def draw_grid(
t: turtle.Turtle,
cols: int,
rows: int,
cell_size: float,
color: str = "gray",
) -> None:
"""
Draw a grid of cells.
Example:
draw_grid(t, 10, 10, 40)
"""
origin_x, origin_y = t.pos()
t.pencolor(color)
for c in range(cols + 1):
t.penup(); t.goto(origin_x + c * cell_size, origin_y)
t.pendown(); t.goto(origin_x + c * cell_size, origin_y + rows * cell_size)
for r in range(rows + 1):
t.penup(); t.goto(origin_x, origin_y + r * cell_size)
t.pendown(); t.goto(origin_x + cols * cell_size, origin_y + r * cell_size)
t.penup()
# ─────────────────────────────────────────────────────────────────────────────
# 3. Fractal and recursive drawings
# ─────────────────────────────────────────────────────────────────────────────
def draw_spiral(
t: turtle.Turtle,
start_length: float = 5,
end_length: float = 200,
step: float = 5,
angle: float = 91,
color_cycle: "list[str] | None" = None,
) -> None:
"""
Draw an outward spiral.
Example:
t = new_turtle(color="purple")
draw_spiral(t, start_length=5, end_length=150, angle=91)
"""
colors = color_cycle or ["red", "orange", "yellow", "green", "blue", "purple"]
length = start_length
i = 0
while length < end_length:
t.pencolor(colors[i % len(colors)])
t.forward(length)
t.right(angle)
length += step
i += 1
def draw_tree(
t: turtle.Turtle,
length: float,
angle: float = 25,
min_length: float = 5,
depth: int = 0,
) -> None:
"""
Draw a recursive fractal tree.
Example:
t = new_turtle(color="brown")
t.left(90) # point upward
draw_tree(t, 80)
"""
if length < min_length:
return
# Color branches green when small (leaves)
if length < min_length * 3:
t.pencolor("green")
else:
t.pencolor("brown")
t.pensize(max(1, int(length / 15)))
t.forward(length)
t.left(angle)
draw_tree(t, length * 0.7, angle, min_length, depth + 1)
t.right(angle * 2)
draw_tree(t, length * 0.7, angle, min_length, depth + 1)
t.left(angle)
t.backward(length)
def draw_Koch_snowflake(
t: turtle.Turtle,
length: float,
depth: int,
) -> None:
"""
Draw one side of a Koch snowflake (call 3 times at 120° for full snowflake).
Example:
t = new_turtle(color="cyan")
for _ in range(3):
draw_Koch_snowflake(t, 300, depth=4)
t.right(120)
"""
if depth == 0:
t.forward(length)
return
length /= 3
draw_Koch_snowflake(t, length, depth - 1)
t.left(60)
draw_Koch_snowflake(t, length, depth - 1)
t.right(120)
draw_Koch_snowflake(t, length, depth - 1)
t.left(60)
draw_Koch_snowflake(t, length, depth - 1)
# ─────────────────────────────────────────────────────────────────────────────
# 4. Spirograph
# ─────────────────────────────────────────────────────────────────────────────
def draw_spirograph(
t: turtle.Turtle,
R: float,
r: float,
d: float,
steps: int = 1000,
color_cycle: "list[str] | None" = None,
) -> None:
"""
Draw a hypotrochoid (spirograph pattern).
R = outer radius, r = inner radius, d = pen distance from inner circle center.
Example:
t = new_turtle()
draw_spirograph(t, R=120, r=75, d=60)
"""
colors = color_cycle or ["red", "blue", "green", "purple"]
for i in range(steps + 1):
theta = 2 * math.pi * i / steps
x = (R - r) * math.cos(theta) + d * math.cos((R - r) / r * theta)
y = (R - r) * math.sin(theta) - d * math.sin((R - r) / r * theta)
if i == 0:
t.penup()
t.goto(x, y)
t.pendown()
else:
t.pencolor(colors[(i * len(colors) // steps) % len(colors)])
t.goto(x, y)
# ─────────────────────────────────────────────────────────────────────────────
# Demo (headless batch mode — no window stays open)
# ─────────────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
import os
# Only open a window if a display is available
if not os.environ.get("DISPLAY") and os.name != "nt":
print("No display available — skipping turtle demo")
else:
print("=== turtle demo ===")
screen = setup_screen(900, 700, bg="black", title="turtle demo")
screen.tracer(0)
# ── spiral ────────────────────────────────────────────────────────────
t1 = new_turtle(speed=0)
draw_spiral(t1, start_length=3, end_length=180, angle=91)
# ── snowflake ──────────────────────────────────────────────────────────
t2 = new_turtle(color="cyan", speed=0)
t2.penup(); t2.goto(200, -100); t2.pendown()
for _ in range(3):
draw_Koch_snowflake(t2, 180, depth=3)
t2.right(120)
# ── polygon grid ──────────────────────────────────────────────────────
t3 = new_turtle(color="white", speed=0)
t3.penup(); t3.goto(-450, -200); t3.pendown()
for i in range(6):
t3.penup(); t3.goto(-450 + i * 55, -200); t3.pendown()
draw_polygon(t3, i + 3, 25, fill_color=
["red","orange","yellow","green","blue","violet"][i])
# ── spirograph ────────────────────────────────────────────────────────
t4 = new_turtle(speed=0)
t4.penup(); t4.goto(-450, 200); t4.pendown()
draw_spirograph(t4, R=80, r=50, d=40, steps=800)
screen.update()
print(" drawing complete — close window to exit")
turtle.done()
For the Pillow (PIL, PyPI) alternative — PIL.Image, PIL.ImageDraw.Draw, and PIL.ImageFont provide raster image drawing without a GUI window, supporting PNG/JPEG export, text rendering, and complex compositing — use Pillow when you need to generate image files programmatically (reports, thumbnails, QR codes) or run headless on a server; use turtle when you want an interactive animated window for educational demos, live debugging, or visual algorithm exploration. For the matplotlib (PyPI) alternative — matplotlib.pyplot.plot() produces publication-quality charts, scatter plots, and vector graphics with data binding and LaTeX labels — use matplotlib for data visualization and scientific plots; use turtle for algorithmic art, recursive fractals, learning Python, and simple animations where the drawing-command metaphor (forward/right/pendown) maps naturally to the algorithm being demonstrated. The Claude Skills 360 bundle includes turtle skill sets covering batch_draw()/filled() context managers, setup_screen()/new_turtle() factory helpers, draw_polygon()/draw_star_simple()/draw_grid() shapes, draw_spiral()/draw_tree()/draw_Koch_snowflake() fractal generators, and draw_spirograph() hypotrochoid renderer. Start with the free tier to try turtle graphics patterns and turtle pipeline code generation.