Pulsar map
after Carl Sagan, Frank Drake and Linda Salzman Sagan, Pioneer plaque, 19721
Fourteen binary-ticked rays leave the Sun as on the Pioneer plaque. The long one to the galactic centre is lit.
Made with Claude Opus 5.5
- Technique
- technical drawing
- Inspired by
- scientific illustration
- Shape
- Any screen
- Added
- 27 September 2026
Colours
- #1C1B1Abackground
- #DAD8CEforeground
- #CF6A4Caccent
Export
Notes
On the plaques carried by Pioneer 10 and 11, each line points from the Sun towards a pulsar and gives that pulsar’s period as a binary number, counted in units of the hydrogen hyperfine transition, about 0.7 nanoseconds. The two linked circles by the end of the long line are the plaque’s hydrogen symbol, which defines that unit.
Here a tick across a ray is a 1 and a short dash along it is a 0. The ray lengths are set for the composition, where the plaque’s give relative distances, and the rays to the Crab pulsar and its near neighbour are spread five degrees apart so both can be seen.
Sources
- Carl Sagan, Frank Drake and Linda Salzman Sagan, Pioneer plaque, 1972. ↑
Source code
wallpapers/pulsar-map/design.py, 66 lines
"""The Pioneer plaque's pulsar map as line drawing: fourteen rays from the Sun ending in binary period ticks, and one long line to the galactic centre."""
from walldye import ACCENT, UI, UI_ALT, Canvas, P, Vec, design
HYDROGEN = 7.04024e-10 # hyperfine transition period (s), the plaque's unit of time
STEP, TICK, DASH = 6, 10, 4 # bit pitch; a '1' tick across the ray, a '0' dash along it
GAP, EDGE = 26, 140 # clear radius round the Sun; galactic-centre line end to the screen edge
SUN_X = 640 # least landscape Sun x, so the rays reaching 522 units left keep a margin
H_R, H_SPAN, H_DROP = 26, 128, 80 # hydrogen glyph: atom radius, atom spacing, offset from line
# (name, galactic longitude deg, ray length px, period s); lengths are composed, not the plaque's distances.
# B0525+21 and the Crab sit 0.7deg apart on the plaque; they are spread to 5deg so the two rays read as two.
PULSARS = [
("B1727-47", 342.6, 560, 0.829823),
("B1240-64", 302.1, 400, 0.388481),
("B1133+16", 241.9, 440, 1.187911),
("B0833-45", 263.6, 320, 0.089290),
("B0525+21", 181.5, 390, 3.745539),
("B0531+21", 186.5, 525, 0.033085),
("B0823+26", 197.0, 430, 0.530661),
("B0950+08", 228.9, 300, 0.253065),
("B1929+10", 47.4, 590, 0.226518),
("B1933+16", 52.4, 350, 0.358736),
("B1451-68", 313.9, 290, 0.263377),
("B1642-03", 14.1, 720, 0.387690),
("B2016+28", 68.1, 440, 0.557953),
("B1508+55", 91.3, 310, 0.739681),
]
@design(aspects="any")
def draw(s: Canvas) -> None:
# Landscape: the Sun a third in, the galactic centre off to the right. Portrait: the map
# turned a quarter turn, so that line runs up the tall screen.
sun = s.pick(landscape=(1 / 3, 0.52), portrait=(0.52, 0.62))
if s.landscape:
sun, gc = Vec(max(sun.x, SUN_X), sun.y), Vec(1, 0)
end = Vec(s.w - EDGE, sun.y)
else:
gc = Vec(0, -1)
end = Vec(sun.x, EDGE)
rays, code = P(), P()
for _, lon, length, period in PULSARS:
u = gc.rotate(deg=-lon) # longitude runs counter-clockwise on screen
n = u.perp()
bits = f"{round(period / HYDROGEN):b}"
d0 = length - STEP * (len(bits) - 0.5)
# The ray breaks into the code: '1' a tick across the ray, '0' a short dash along it.
rays.M(sun + u * GAP).L(sun + u * (d0 - STEP))
for k, b in enumerate(bits):
c = sun + u * (d0 + k * STEP)
if b == "1":
code.M(c + n * (TICK / 2)).L(c - n * (TICK / 2))
else:
code.M(c - u * (DASH / 2)).L(c + u * (DASH / 2))
s.stroke(rays, UI, 1.2)
s.stroke(code, UI_ALT, 1.5)
s.stroke(P().M(sun + gc * GAP).L(end), ACCENT, 2.5)
# The hydrogen glyph captions the galactic-centre line, flush with its end.
near = end + gc.perp() * H_DROP - gc * H_R
far = near - gc * H_SPAN
atoms = P().circle(near, H_R).circle(far, H_R).M(far + gc * H_R).L(near - gc * H_R)
s.stroke(atoms, UI_ALT, 1.8)
s.fill(P().circle(near, 4).circle(far, 4), UI_ALT)
s.fill(P().circle(sun, 11), ACCENT)"""The Pioneer plaque's pulsar map as line drawing: fourteen rays from the Sun ending in binary period ticks, and one long line to the galactic centre."""
from walldye import ACCENT, UI, UI_ALT, Canvas, P, Vec, design
HYDROGEN = 7.04024e-10 # hyperfine transition period (s), the plaque's unit of time
STEP, TICK, DASH = 6, 10, 4 # bit pitch; a '1' tick across the ray, a '0' dash along it
GAP, EDGE = 26, 140 # clear radius round the Sun; galactic-centre line end to the screen edge
SUN_X = 640 # least landscape Sun x, so the rays reaching 522 units left keep a margin
H_R, H_SPAN, H_DROP = 26, 128, 80 # hydrogen glyph: atom radius, atom spacing, offset from line
# (name, galactic longitude deg, ray length px, period s); lengths are composed, not the plaque's distances.
# B0525+21 and the Crab sit 0.7deg apart on the plaque; they are spread to 5deg so the two rays read as two.
PULSARS = [
("B1727-47", 342.6, 560, 0.829823),
("B1240-64", 302.1, 400, 0.388481),
("B1133+16", 241.9, 440, 1.187911),
("B0833-45", 263.6, 320, 0.089290),
("B0525+21", 181.5, 390, 3.745539),
("B0531+21", 186.5, 525, 0.033085),
("B0823+26", 197.0, 430, 0.530661),
("B0950+08", 228.9, 300, 0.253065),
("B1929+10", 47.4, 590, 0.226518),
("B1933+16", 52.4, 350, 0.358736),
("B1451-68", 313.9, 290, 0.263377),
("B1642-03", 14.1, 720, 0.387690),
("B2016+28", 68.1, 440, 0.557953),
("B1508+55", 91.3, 310, 0.739681),
]
@design(aspects="any")
def draw(s: Canvas) -> None:
# Landscape: the Sun a third in, the galactic centre off to the right. Portrait: the map
# turned a quarter turn, so that line runs up the tall screen.
sun = s.pick(landscape=(1 / 3, 0.52), portrait=(0.52, 0.62))
if s.landscape:
sun, gc = Vec(max(sun.x, SUN_X), sun.y), Vec(1, 0)
end = Vec(s.w - EDGE, sun.y)
else:
gc = Vec(0, -1)
end = Vec(sun.x, EDGE)
rays, code = P(), P()
for _, lon, length, period in PULSARS:
u = gc.rotate(deg=-lon) # longitude runs counter-clockwise on screen
n = u.perp()
bits = f"{round(period / HYDROGEN):b}"
d0 = length - STEP * (len(bits) - 0.5)
# The ray breaks into the code: '1' a tick across the ray, '0' a short dash along it.
rays.M(sun + u * GAP).L(sun + u * (d0 - STEP))
for k, b in enumerate(bits):
c = sun + u * (d0 + k * STEP)
if b == "1":
code.M(c + n * (TICK / 2)).L(c - n * (TICK / 2))
else:
code.M(c - u * (DASH / 2)).L(c + u * (DASH / 2))
s.stroke(rays, UI, 1.2)
s.stroke(code, UI_ALT, 1.5)
s.stroke(P().M(sun + gc * GAP).L(end), ACCENT, 2.5)
# The hydrogen glyph captions the galactic-centre line, flush with its end.
near = end + gc.perp() * H_DROP - gc * H_R
far = near - gc * H_SPAN
atoms = P().circle(near, H_R).circle(far, H_R).M(far + gc * H_R).L(near - gc * H_R)
s.stroke(atoms, UI_ALT, 1.8)
s.fill(P().circle(near, 4).circle(far, 4), UI_ALT)
s.fill(P().circle(sun, 11), ACCENT)
Run it yourself
$ git clone https://github.com/nickolaj-jepsen/walldye && cd walldye$ uv run walldye render pulsar-map --theme fireproof -o pulsar-map-fireproof-16x9.svg