Advanced · Turing patterns

Lesson 9: Grids and diffusion

Build the turing patterns in Python, and learn on the way:

  • 2-D arrays as a grid of cells
  • np.roll for neighbours, with edges that wrap around
  • the Laplacian: a cell against its neighbours
  • updating a whole grid in one line
  • showing an array with plt.imshow

Watch it first

Plays from YouTube after a click.

turing-patterns.py
"""Turing patterns: the Gray-Scott reaction-diffusion rule on a 128 x 128 grid.
Run: python turing-patterns.py   (needs: pip install numpy matplotlib; takes a few seconds)
"""
import numpy as np
import matplotlib.pyplot as plt

plt.style.use("dark_background")

size, steps = 128, 6000
f, k = 0.0545, 0.062  # feed and kill rates: coral
DA, DB = 1.0, 0.5  # A spreads twice as fast as B

A, B = np.ones((size, size)), np.zeros((size, size))
rng = np.random.default_rng()
for y, x in rng.integers(10, size - 18, (6, 2)):
    B[y : y + 8, x : x + 8] = 1.0  # six drops of B


def laplacian(Z):
    """Each cell against its neighbours: 0.2 for the four sides, 0.05 for the corners (Karl Sims)"""
    sides = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)
    corners = (np.roll(np.roll(Z, 1, 0), 1, 1) + np.roll(np.roll(Z, 1, 0), -1, 1)
               + np.roll(np.roll(Z, -1, 0), 1, 1) + np.roll(np.roll(Z, -1, 0), -1, 1))
    return 0.2 * sides + 0.05 * corners - Z


for _ in range(steps):
    reaction = A * B * B  # one A and two B make three B
    A += DA * laplacian(A) - reaction + f * (1 - A)
    B += DB * laplacian(B) + reaction - (f + k) * B

plt.figure(figsize=(6, 6))
plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)
plt.axis("off")
plt.show()

# Try: f, k = 0.039, 0.058 (a cell net) or 0.034, 0.063 (spots) -> the same rule, another pattern

No Python on this computer? The notebook runs the same script, the exercises and the answers in your browser, on Google Colab.

Line by line

  1. A, B = np.ones((size, size)), np.zeros((size, size))

    Two 128 × 128 grids: the food A everywhere, no B yet.

  2. B[y : y + 8, x : x + 8] = 1.0

    A drop of B: an 8 × 8 square of the grid, set at once by slicing.

  3. def laplacian(Z):

    How much a cell differs from its neighbours: positive where the neighbours have more, so diffusion fills it up.

  4. sides = np.roll(Z, 1, 0) + np.roll(Z, -1, 0) + np.roll(Z, 1, 1) + np.roll(Z, -1, 1)

    np.roll shifts the whole grid by one cell up, down, left or right; the edges wrap around, so the dish has no border.

  5. reaction = A * B * B

    The reaction, one A and two B make three B, for every cell at once.

  6. A += DA * laplacian(A) - reaction + f * (1 - A)

    The Gray–Scott rule for A: it spreads, is eaten, and is fed back towards 1 at the rate f.

  7. plt.imshow(B, cmap="magma", vmin=0, vmax=0.5)

    The grid of B as a picture, one pixel per cell.

Try it yourself

  1. Try f, k = 0.034, 0.063.

    Hint

    One line near the top.

    Answer

    Spots: round patches of B, evenly spaced, instead of the coral’s winding lines.

  2. Make B spread as fast as A: DB = 1.0. What happens?

    Hint

    DA, DB = 1.0, 1.0.

    Answer

    No pattern at all: the drops fade away to nothing. Without A spreading faster than B, nothing holds the patches apart. This is Turing’s point.

  3. Use one drop in the middle instead of six.

    Hint

    Replace the loop with B[60:68, 60:68] = 1.0.

    Answer

    The coral grows outwards from the one drop with a fourfold symmetry that copies the square drop: one seed gives an ordered pattern, six random drops a natural-looking one.

Quiz

1. What does np.roll(Z, 1, 0) do?
2. What does the Laplacian of a cell measure?
3. Why is there no loop over the cells?
4. What did Turing show in 1952?
5. What changes from coral to spots?

Flashcards

Read the front, say the back to yourself, then open the card.

  • np.roll(Z, shift, axis)

    Shifts an array along an axis; what falls off one end comes back at the other.

  • Laplacian

    A cell’s neighbours minus the cell itself: where diffusion will move it.

  • Gray–Scott

    A is fed in at f, B is removed at f + k, and A + 2B → 3B.

  • Turing instability

    Diffusion breaks an even mixture into a pattern when one substance spreads faster.

  • plt.imshow(grid)

    Shows a 2-D array as a picture, one pixel per cell.

These flashcards on their own page →

You built all nine. If the course helped, the channel would love to hear it. Support the channel →