How to Create a Spiral Art with Python

I like small projects that give an instant payoff. A spiral is perfect for that: a handful of lines, a press of Run in python, and you get clean geometric art you can tweak for hours. Below I walk through my original snippet, rebuild it into a handy draw_spiral() function, and show a few tricks I use when I want the pattern to feel fresh.

My Code

numpy as np
import matplotlib.pyplot as plt

# --- generate an Archimedean spiral ---------------------------------
theta = np.linspace(0, 12 * np.pi, 2000) # angle values
a = 0.15 # tightness factor
r = a * theta # radius grows linearly

x = r * np.cos(theta)
y = r * np.sin(theta)

# --- plot ------------------------------------------------------------
plt.figure(figsize=(6, 6))
plt.plot(x, y, linewidth=2)
plt.axis("off")
plt.show()

How The Original Snippet Work

LineWhat it doesWhy it matters to me
import numpy as npPulls in NumPy.I need a fast way to create thousands of angle values.
import matplotlib.pyplot as pltLoads Matplotlib.This is my drawing pen.
theta = np.linspace(0, 12 * np.pi, 2000)Makes 2 000 evenly spaced angles from 0 to 12π (≈ 6 turns).More points = smoother curve.
a = 0.15Sets how far each loop sits from the last.Smaller a = tight coil, bigger a = wide arms.
r = a * thetaFinds a radius for every angle.Linear growth = Archimedean spiral (good for even spacing).
x = r * np.cos(theta)
y = r * np.sin(theta)
Converts polar to (x, y) pairs.Matplotlib speaks Cartesian.
plt.figure(figsize=(6, 6))Opens a 6-inch square canvas.A square keeps the shape centered.
plt.plot(x, y, linewidth=2)Draws one continuous line.A width of 2 is easy on the eyes.
plt.axis("off")Hides ticks and labels.I want art, not axes.
plt.show()Pops the figure on screen.Without this, nothing appears in many IDEs.

Explain Code

I often want quick variations different colours, rotated copies, maybe a filled version without rewriting those ten lines each time. So I wrapped the logic in a function:

numpy as np
import matplotlib.pyplot as plt

def draw_spiral(a=0.15, # tightness
turns=6, # full rotations (6 = 12π radians)
linewidth=2,
color='tab:orange',
offset_deg=0, # rotate the whole thing
fill=False,
save_path=None,
show=True):
"""Draw an Archimedean spiral with a few knobs."""

# build the angle array
theta_max = turns * 2 * np.pi
theta = np.linspace(0, theta_max, int(theta_max * 160)) # ~160 pts / rad
r = a * theta

# optional rotation
theta_shifted = theta + np.deg2rad(offset_deg)

# polar → Cartesian
x = r * np.cos(theta_shifted)
y = r * np.sin(theta_shifted)

# plot
fig, ax = plt.subplots(figsize=(6, 6))
ax.plot(x, y, lw=linewidth, color=color)
if fill:
ax.fill(x, y, color=color, alpha=0.15)

ax.set_aspect('equal')
ax.axis('off')

if save_path:
fig.savefig(save_path, dpi=300, bbox_inches='tight', transparent=True)

if show:
plt.show()

return fig, ax

Experiments I Run all The Time

# A super-tight, long swirl
draw_spiral(a=0.05, turns=15, linewidth=1.2, color='purple')

# Two offset spirals for a nautilus look
draw_spiral(a=0.12, turns=8, color='skyblue', fill=True, show=False)
draw_spiral(a=0.12, turns=8, offset_deg=180, color='salmon', fill=True)

# Save a crisp SVG for Illustrator
draw_spiral(a=0.18, turns=5, linewidth=4,
color='black', save_path='spiral.svg')

Hands on Extra When I Want to Play

  • Interactive sliders
ipywidgets import interact
interact(draw_spiral,
a=(0.01, 0.5, 0.01),
turns=(1, 20, 1),
linewidth=(0.5, 10, 0.5),
offset_deg=(0, 360, 5),
fill=False,
show=True);

Move the knobs in a Jupyter notebook to see changes live.

  • Colour gradients
    Map theta to a colormap and pass a LineCollection to Matplotlib for a smooth fade from centre to edge.
  • Simple animation
    With matplotlib.animation.FuncAnimation, increase theta_max frame by frame—export as a looping GIF.
  • Try other spirals
    Logarithmic r = b * np.exp(c θ) or Fermat r = k √θ for very different vibes.
  • Add jitter
    x += np.random.normal(scale=0.02, size=x.size) gives an ink-on-paper feel.
  • Tile for wallpaper
    Loop over offsets and colours in a grid of subplots—psychedelic in seconds.

Final Thought

A spiral may look like pure maths, but to me it’s a playground. Each parameter is a knob I can spin for instant feedback: tighter, looser, lighter, louder. The code above started as ten quick lines; now it’s a mini tool I reach for whenever I need background art, a logo seed, or just a quiet break from “serious” work.

Related blog posts