Natural selection

Birds eat the moths they can see. Turn the bark dark with soot or light with clean air and watch dark and light moths rise and fall over 60 generations, with chance (drift) in small populations and, at Class 12 level, p, q and a Hardy-Weinberg check.

Keep it one tap away for everyday use.

Bookmark Natural selection?

Press Ctrl + D now. Your browser opens its own bookmark box, where you choose the name and folder.

  1. Set up
  2. Watch
  3. Graph
  4. Check
Nothing is uploadedWorks offline once open

A teaching model: the survival numbers are made up, not measurements from real moth studies.

Level
Tree bark
Moths
Mutation

Mutation: now and then a copying mistake turns a light allele (c) into a dark one (C). This is the chance for each light allele in each generation, so a few new dark moths keep appearing even while birds eat them.

Over the generations

The solid line is this run; the dashed line is what happens on average with no chance at all.

Download

Try this

  • Choose Soot comes. How many generations after the bark turns dark do dark moths become most of the population?
  • Set the birds to 0 %. Does the dark allele still change? Try 50 moths, then 5000.
  • Choose Clean air. Why do light moths come back more slowly than dark ones spread? (Hint: light moths are cc, and the c allele hides in dark Cc moths.)
  • Class 12: watch the Hardy-Weinberg check. The newborns fit p², 2pq, q² even while selection is changing p.

Check yourself

Fresh questions every time. Nothing is saved.

    What it does

    Peppered moths rest on tree trunks by day. Most used to be pale and speckled, hidden against pale bark covered in lichen. When factory smoke blackened the trees, a dark form became common, because birds found the pale moths more easily on the dark bark. When the air was cleaned, pale moths came back. This simulator lets you replay that story and change it:

    • Tree bark: always light, always dark, soot comes (bark turns dark at generation 10) or clean air (bark turns light at generation 10).
    • Birds: the share of visible moths eaten each generation.
    • Dark allele at the start: the dark form comes from one dominant allele, C. Light moths are cc.
    • Moths: 50, 500 or 5000 moths (the default), or no chance (the average path). In small populations luck matters too: that is genetic drift.
    • Mutation: the chance, each generation, that a light allele c is miscopied into a dark allele C (off, 1 in 100,000, 1 in 10,000 as the default, or 1 in 1,000). It keeps a trickle of new dark moths appearing, as happened in real moth populations.

    While the bark is still light, birds eat most of the few dark moths. In a small population the last dark allele can then be lost by pure chance before the soot arrives; that is genetic drift, and the page says so when it happens. With mutation off, a lost allele never comes back, so selection has nothing to work on. With 5000 moths and a little mutation this almost never happens. To see drift on its own, with many populations side by side, use the wright-Fisher simulator.

    The trunk picture shows the moths of one generation, with the eaten ones crossed out; slide Generation or press Play to move through time. The graph shows the share of dark moths over 60 generations. It fits Class 10 Science: heredity and evolution (variation, natural selection) and Class 12 Biology: evolution (natural selection, the Hardy-Weinberg principle, gene flow and genetic drift). The moth colour gene works like Mendel’s tall and short peas in mendel's pea garden; check real genotype counts with hardy-Weinberg tester, work out p and q from data with allele frequency calculator, and see how populations grow in population growth models.

    How to use it

    1. Pick the level. Class 10 shows the moths, the eaten ones and the % dark. Class 12 adds genotypes CC, Cc and cc, the allele frequencies p and q, and a Hardy-Weinberg check of the newborns.
    2. Pick the bark and set how hard the birds hunt.
    3. Set the dark allele at the start. The label shows what share of moths that makes dark (1 − q²).
    4. Pick the number of moths and the mutation rate. Press New run to see a fresh run with the same settings; with 50 moths no two runs look alike.
    5. Slide the generation or Play. Download every generation as a CSV file, or the picture and graph as an image, PDF or Word file.
    6. Check yourself gives fresh questions each time.

    Worked example

    Open the page: soot comes at generation 10, birds catch 30 % of the moths they can see, and the dark allele starts at 5 % (so about 9.8 % of moths are dark, because CC and Cc moths are both dark: 1 − 0.95² = 0.0975). With no chance and the default mutation rate of 1 in 10,000, dark moths fall while the bark is still light (to 0.4 % by generation 10), then rise once the bark turns dark: about 74 % of moths are dark by generation 30 and 98.9 % by generation 60. With 5000 moths a run follows much the same path. At Class 12 level with 500 moths, the facts show p = (2 × CC + Cc) ÷ (2 × 500) for the newborns and the Hardy-Weinberg expectation p² : 2pq : q², which the newborns fit because they come from random mating.

    Tips

    • Selection only works on variation that is already there. If the dark allele starts at 0 %, nothing can happen: try 1 %.
    • Light moths come back slowly after clean air because the c allele hides in dark Cc moths, where birds cannot “see” it.
    • Set the birds to 0 % and use 50 moths to see drift on its own.
    • Try soot comes with 500 or 50 moths and mutation off, and press New run a few times: often the dark allele is lost before the soot arrives, and the dark moths never come back.

    FAQ

    Is the dark colour caused by the soot? No. The moths do not change colour. Dark moths are born dark because of the allele they inherit; soot only changes which moths the birds find.

    Why do the newborns fit Hardy-Weinberg if selection is happening? Random mating rebuilds p², 2pq, q² every generation. Selection changes p between generations, so the population is not in balance over time.

    Are these real survival numbers? No, they are teaching values you can change.

    Where the numbers come from

    • The selection model (dark allele dominant, survival 1 − s for the moth that does not match the bark, random mating) is standard population genetics, written by fibub and checked in the tests against a separate genotype-by-genotype Python version over 40 generations.
    • The Hardy-Weinberg chi-square p-value (1 degree of freedom) was checked against Python's math.erfc.
    • Survival numbers, start frequencies and the generation when soot arrives are made-up teaching values, not data from real moth studies. Drawings are fibub's own. Nothing you enter is stored or sent anywhere.

    Standard scientific values, such as constants, atomic weights and melting points, are facts found in every textbook; we name where ours were checked. If you are an author or publisher and want a value, a credit or a table changed or removed, tell us and we will act quickly.

    Read more on the Blog

    Last updated 2026-11-09.

    Change log for Natural selection

    1. Fix #1126 drift in the soot story Details on GitHub
    2. Add #1126 Natural selection with peppered moths Details on GitHub

    Every change to fibub

    Related tools

    Hardy-Weinberg tester #T206 Test whether one sample's genotype counts fit Hardy-Weinberg proportions. Gives allele frequencies, observed and expected heterozygosity, the inbreeding coefficient F, chi-square with optional continuity correction, and the exact test (two-sided and one-sided), with a de Finetti diagram. Also handles three or more alleles by chi-square. Population growth models #T218 Compare exponential and logistic growth from a starting size, growth rate r and carrying capacity K, or project an age-structured population with a Leslie matrix and get λ, the stable age distribution, reproductive values, R₀ and generation time. Allele frequency calculator #T227 Type or paste genotype counts (AA, AB, BB) for one or more populations. Get allele and genotype frequencies, expected Hardy-Weinberg counts, the chi-square test and the exact test, observed and expected heterozygosity, and F-statistics (FIS, FST, FIT) by Weir and Cockerham or Nei. Mendel's pea garden #L58 Cross tall and short pea plants, or round yellow and wrinkled green seeds, and grow 20, 100 or 1000 random children. Compare the counts with 3 : 1 and 9 : 3 : 3 : 1, see the Punnett square, and at Class 12 level add incomplete dominance, codominance (ABO) and a chi-square check. Food web builder #L63 Explore a forest or pond food web drawn by trophic level. Tap to add or remove who eats whom, remove a species and see who dies out or increases, count the food chains, and read the energy pyramid with the 10 % rule. Taxonomy ladder #L244 Put two organisms side by side on a ladder from kingdom down to species (human, tiger, lion, cat, dog, peafowl, housefly, honey bee, mango, neem, wheat, rice) and see the rungs they share joined together: the lower they stay together, the closer they are related. Plus a game to put the seven ranks in order. Pedigree analyser #L288 Tap the people in a three-generation family tree to mark who has a trait, and see at once which inheritance patterns fit: autosomal dominant or recessive, X-linked dominant or recessive, or Y-linked. Each ruled-out pattern gives the family that breaks it, and the tree marks who must be a carrier. Made-up teaching families only. Polygenic traits #L289 Choose 1 to 6 genes with additive alleles and cross two all-heterozygous parents. See the 2n + 1 height classes and their ratio (1 : 2 : 1, 1 : 4 : 6 : 4 : 1 …) grow into a bell curve, add environmental spread to smooth it, and grow 1000 random children to compare. Geological time #L292 Move through Earth's 4.54 billion years and see the eon, era and period of any age, when major forms of life first appeared, and where each event would fall if all of Earth's history were one calendar year or one 24-hour day. Predator and prey #L295 Watch hares and lynx rise and fall in turn. Slide the prey birth rate, catch rate, predator gain and death rate and see both populations over time, the loop in the phase plot, the still point and how a prey limit damps the swings. Then sort every species interaction by its + / − / 0 signs. Inhibition zones #L297 Put antibiotic discs on a Petri dish of bacteria and see clear zones where growth is stopped. Change the amount in each disc and the agar depth, swap to a resistant strain, and see why the zone edge sits where the antibiotic falls to the germ's MIC. A teaching model. Copying errors #L318 Copy a 60-base DNA string again and again with a small chance of a wrong base each time, and watch the changes pile up. Compare the average with length times rate times generations.