Legacy and Refinements

After the discovery: how close was Le Verrier, and what modern tools reveal.
Author

Jonathan Whitmore

Published

April 9, 2026

The Night of September 23

On the evening of 23 September 1846, Johann Galle opened a letter from a Frenchman he had never met. Le Verrier’s final prediction — refined in his third memoir of 31 August — gave specific coordinates for an unknown planet. That same night, Galle and his student Heinrich d’Arrest pointed the Berlin Observatory’s 9-inch Fraunhofer refractor at the predicted position. Within an hour, they found a star-like object not on their charts, very close to the predicted region of sky. Contemporary accounts describe the discovery as being within about a degree of Le Verrier’s search position.

Code
from discoverneptune.historical_values import (
    LEVERRIER_MEMOIR_1845,
    LEVERRIER_MEMOIR_1846_JUN,
    LEVERRIER_MEMOIR_1846_AUG,
    GALLE_OBSERVATION,
    MODERN_NEPTUNE,
)

# Le Verrier's published longitude vs Galle's observation
pred = LEVERRIER_MEMOIR_1846_AUG
obs = GALLE_OBSERVATION

lon_error = abs(pred.longitude_deg - obs.longitude_deg)
dist_error_pct = abs(pred.semi_major_axis_au - MODERN_NEPTUNE.semi_major_axis_au) / MODERN_NEPTUNE.semi_major_axis_au * 100

print("Le Verrier's prediction (Aug 1846):")
print(f"  Published longitude: {pred.longitude_deg:.2f}\u00b0 (quoted for 1 Jan 1847)")
print(f"  Predicted distance:  {pred.semi_major_axis_au:.3f} AU")
print()
print("Galle's observation, reduced to 1 Jan 1847:")
print(f"  Inferred longitude:  {obs.longitude_deg:.1f}\u00b0")
print(f"  Reference equinox:   {obs.longitude_equinox}")
print()
print("Modern Neptune:")
print(f"  True distance:       {MODERN_NEPTUNE.semi_major_axis_au:.3f} AU")
print()
print(f"Common-epoch longitude offset: {lon_error:.2f}\u00b0")
print(f"Distance error:   {dist_error_pct:.1f}% — Le Verrier overestimated the distance")
Le Verrier's prediction (Aug 1846):
  Published longitude: 326.53° (quoted for 1 Jan 1847)
  Predicted distance:  36.154 AU

Galle's observation, reduced to 1 Jan 1847:
  Inferred longitude:  327.4°
  Reference equinox:   1847-01-01

Modern Neptune:
  True distance:       30.069 AU

Common-epoch longitude offset: 0.87°
Distance error:   20.2% — Le Verrier overestimated the distance

The published longitude remained impressively close to Neptune’s inferred position: both values above are quoted for 1 January 1847. The distance was not accurate — but as we saw in the previous chapter, this reflects the mass-distance degeneracy inherent in the inverse problem, not a failure of Le Verrier’s method.

Code
import matplotlib.pyplot as plt
import numpy as np

pred_jun = LEVERRIER_MEMOIR_1846_JUN.longitude_deg
pred_aug = LEVERRIER_MEMOIR_1846_AUG.longitude_deg
obs_galle = GALLE_OBSERVATION.longitude_deg


def _build(theme="light"):
    apply_style(theme)
    pal = palette(theme)
    cycle = category_cycle(theme)
    # cycle[0]: Jun prediction; cycle[1]: Aug prediction; pal.before: Galle discovery
    col_jun = cycle[0]
    col_aug = cycle[1]
    col_galle = pal.before

    fig, ax = plt.subplots(figsize=(10, 2.6))

    # The ±1° search window around Le Verrier's August prediction is shaded.
    ax.axvspan(pred_aug - 1.0, pred_aug + 1.0, color=col_galle, alpha=0.15,
               label="Galle's 1° search window")

    ax.plot([pred_jun], [1.0], marker="v", ms=14, color=col_jun,
            label="Le Verrier, Jun 1846")
    ax.plot([pred_aug], [1.0], marker="v", ms=14, color=col_aug,
            label="Le Verrier, Aug 1846 (sent to Galle)")
    ax.plot([obs_galle], [0.0], marker="*", ms=22, color=col_galle,
            markeredgecolor=pal.truth, label="Galle observation, reduced to 1 Jan 1847")

    # Annotate each marker
    ax.annotate(f"{pred_jun:.1f}°", (pred_jun, 1.0), xytext=(0, 14),
                textcoords="offset points", ha="center", fontsize=9, color=col_jun)
    ax.annotate(f"{pred_aug:.1f}°", (pred_aug, 1.0), xytext=(0, 14),
                textcoords="offset points", ha="center", fontsize=9, color=col_aug)
    ax.annotate(f"{obs_galle:.1f}°", (obs_galle, 0.0), xytext=(0, -22),
                textcoords="offset points", ha="center", fontsize=9, color=col_galle)

    ax.set_xlim(pred_jun - 4, obs_galle + 4)
    ax.set_ylim(-0.9, 1.9)
    ax.set_yticks([])
    ax.set_xlabel("Heliocentric ecliptic longitude (degrees)")
    ax.set_title("Prediction and discovery at a common epoch")
    ax.legend(loc="center left", bbox_to_anchor=(1.01, 0.5), fontsize=9,
              frameon=False)
    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.spines["left"].set_visible(False)
    return fig


display(dual_render(_build, alt="Le Verrier's predicted longitudes and the Galle-derived longitude at the common epoch 1 January 1847"))
Figure 1: Le Verrier’s sky: the predicted longitudes in his June and August 1846 memoirs, the ±1° search window, and the longitude inferred from Galle’s observation. All three heliocentric ecliptic longitudes are reduced to the common epoch 1 Jan 1847.

The longitude inferred from Galle’s observation is less than one degree from the published August longitude when both are reduced to 1 January 1847. That agreement was small enough that pointing the Berlin 9-inch refractor at Le Verrier’s coordinates, on the first clear night after receiving the letter, was enough.

The Adams Priority Dispute

The discovery immediately ignited a priority dispute. John Couch Adams, a young Cambridge mathematician, had been working on the same inverse problem. The account usually given is that by September 1845 he had a solution, told James Challis at the Cambridge Observatory, and was put in touch with the Astronomer Royal, George Airy — calling twice at Greenwich, missing Airy both times, and leaving a note with a predicted position.

That account is less secure than it reads. The archival re-examination that followed the reappearance of Airy’s Neptune file in 1999 found the note “written in a different handwriting to the rest of the message”, dated only vaguely to October 1845, and imprecise about what had actually been computed. Adams’s successive solutions span more than 20°, which is part of why the Cambridge search was misdirected.

The figure itself is worth stating carefully, and on one consistent basis. Reduced to true heliocentric longitude on the day of discovery, the note’s 325°2′ mean longitude becomes 328°41′, against Neptune’s actual 326°57′ — an error of 1°44′. Le Verrier’s first prediction of 1 June was 324°35′, and the 31 August paper Galle actually used gave 325°58′, an error of 59′. So Adams was close, and about twice as far off as Le Verrier’s final figure — but “approximately 330°” both overstates the number and hides how contested it is.

(These are day-of-discovery values, and so differ from the 1 January 1847 figures quoted earlier on this page; the epochs are not interchangeable.)

Challis did search, in the summer of 1846, and the failure was narrower and more painful than “he was too slow” suggests. He recorded Neptune without recognising it, and when checking that his method worked he compared the nights of 4 and 12 August — then stopped at star number 39, satisfied. Neptune was entry 49. Had he carried the comparison a little further he could hardly have missed that it had moved.

The dispute was bitter and nationalistic — French and British partisans each claimed sole credit for their countryman.

The institutions of the day settled it awkwardly, and it is worth separating two societies that are easily confused. The Royal Society simply honoured both with its Copley Medal, Le Verrier first and Adams two years later, each cited for the work on the disturbances of Uranus.

The Royal Astronomical Society could not manage anything so tidy. Its Gold Medal was not awarded to either man for Neptune; instead, after what its Council called “the discussions of last year”, it created a Testimonial awarded jointly — “in place of and in the same rank with the usual medal” — and said explicitly that the joint award “involved no opinion, and justified no inference on the comparative rights of the two”. Presenting it in February 1848, John Herschel put the reasoning plainly: Le Verrier and Adams were “names which, as Genius and Destiny have joined them, I shall by no means put asunder”, and “we have made, we could make, no distinction between them on this occasion”.

Both men did receive the RAS Gold Medal eventually, years later, for other work. The medal for Neptune was never given to anyone.

History has since settled on shared credit: both men solved the same inverse problem independently, using similar methods, arriving at similar answers. Le Verrier published first and triggered the actual observation; Adams’s work, while earlier in some respects, remained unpublished and did not lead to a telescopic search until after the French announcement.

How Well Would the Prediction Have Aged?

Le Verrier’s predicted orbit matched Neptune’s true position in 1846. But his predicted semi-major axis of 36.2 AU (vs the true 30.1 AU) means his orbit had the wrong period. How quickly would the predicted and true Neptune diverge?

Two-body (Kepler) estimate

A simple Keplerian calculation shows the divergence rate. Two orbits with different semi-major axes have different periods, so their longitudes drift apart linearly:

Code
import numpy as np

# Orbital periods from Kepler's third law: P = a^(3/2) in years (for a in AU, M_sun = 1)
a_leverrier = LEVERRIER_MEMOIR_1846_AUG.semi_major_axis_au
a_true = MODERN_NEPTUNE.semi_major_axis_au

P_leverrier = a_leverrier**1.5  # years
P_true = a_true**1.5

# Mean motions (degrees per year)
n_leverrier = 360.0 / P_leverrier
n_true = 360.0 / P_true

# Divergence over 200 years
years_2body = np.arange(0, 201, 1)
divergence_2body = (n_leverrier - n_true) * years_2body  # degrees, predicted − true

print(f"Le Verrier's predicted period: {P_leverrier:.1f} years")
print(f"True Neptune period:           {P_true:.1f} years")
print(f"Mean motion (predicted − true): {n_leverrier - n_true:.4f} deg/year")
print(f"Divergence after 50 years:     {abs((n_true - n_leverrier) * 50):.1f}\u00b0")
print(f"Divergence after 100 years:    {abs((n_true - n_leverrier) * 100):.1f}\u00b0")
print(f"Divergence after 200 years:    {abs((n_true - n_leverrier) * 200):.1f}\u00b0")
Le Verrier's predicted period: 217.4 years
True Neptune period:           164.9 years
Mean motion (predicted − true): -0.5273 deg/year
Divergence after 50 years:     26.4°
Divergence after 100 years:    52.7°
Divergence after 200 years:    105.5°

N-body propagation

The Keplerian estimate ignores gravitational interactions. In reality, Jupiter and Saturn perturb Neptune’s orbit, and a Neptune at 36.2 AU experiences different perturbations than one at 30.1 AU. Let’s run two full N-body simulations to see the actual divergence:

Code
from pathlib import Path
import pandas as pd
import rebound

from discoverneptune.simulation import (
    StateVector,
    NeptuneCandidate,
    build_simulation_from_vectors,
)

# Load bundled state vectors (epoch: 1781-01-01)
from discoverneptune.data import find_bundled_data_dir

data_dir = find_bundled_data_dir()
svs = pd.read_csv(data_dir / "outer_planet_state_vectors_1781_01_01.csv")
state = {
    row.planet: StateVector(row.x, row.y, row.z, row.vx, row.vy, row.vz)
    for row in svs.itertuples(index=False)
}

# Le Verrier's Neptune: use his Aug 1846 parameters
# Align both model orbits at an arbitrary zero longitude on 1 Jan 1847, then
# back-propagate with each orbit's own mean motion. Only their subsequent
# divergence is meaningful; this avoids mixing 1847-equinoctial historical
# longitudes with the simulation's J2000 frame.
from astropy.time import Time

years_since_epoch = (Time("1847-01-01").jd - Time("1781-01-01").jd) / 365.25
lv = LEVERRIER_MEMOIR_1846_AUG
lv_mean_motion_rad = 2 * np.pi / (lv.semi_major_axis_au**1.5)  # rad/yr
lv_longitude_1847_rad = 0.0
lv_longitude_1781_rad = lv_longitude_1847_rad - lv_mean_motion_rad * years_since_epoch

leverrier_neptune = NeptuneCandidate(
    mass_solar=lv.mass_solar,
    a=lv.semi_major_axis_au,
    e=lv.eccentricity if lv.eccentricity is not None else 0.0,
    l_rad=lv_longitude_1781_rad,
)

# Modern Neptune: true orbital elements, aligned at the same arbitrary origin.
modern_longitude_1847_rad = 0.0
modern_mean_motion_rad = 2 * np.pi / (MODERN_NEPTUNE.semi_major_axis_au**1.5)
modern_longitude_1781_rad = modern_longitude_1847_rad - modern_mean_motion_rad * years_since_epoch

modern_neptune = NeptuneCandidate(
    mass_solar=MODERN_NEPTUNE.mass_solar,
    a=MODERN_NEPTUNE.semi_major_axis_au,
    e=MODERN_NEPTUNE.eccentricity if MODERN_NEPTUNE.eccentricity is not None else 0.0,
    l_rad=modern_longitude_1781_rad,
)

# Build two simulations
sim_lv = build_simulation_from_vectors(
    state["jupiter"], state["saturn"], state["uranus"], leverrier_neptune
)
sim_mod = build_simulation_from_vectors(
    state["jupiter"], state["saturn"], state["uranus"], modern_neptune
)

# Integrate both for 266 years (1781 + 266 = 2047, 200 years past the epoch)
# Record Neptune longitude at each step
integration_years = 266
sample_times = np.linspace(0, integration_years, 500)

lon_lv = np.empty(len(sample_times))
lon_mod = np.empty(len(sample_times))

for i, t in enumerate(sample_times):
    sim_lv.integrate(t)
    nep_lv = sim_lv.particles[-1]
    sun_lv = sim_lv.particles[0]
    lon_lv[i] = np.degrees(np.arctan2(nep_lv.y - sun_lv.y, nep_lv.x - sun_lv.x))

    sim_mod.integrate(t)
    nep_mod = sim_mod.particles[-1]
    sun_mod = sim_mod.particles[0]
    lon_mod[i] = np.degrees(np.arctan2(nep_mod.y - sun_mod.y, nep_mod.x - sun_mod.x))

# Compute divergence (unwrap to handle 360-deg wrapping)
years_since_1846 = sample_times - years_since_epoch
divergence_nbody = np.unwrap(np.radians(lon_lv - lon_mod))
divergence_nbody = np.degrees(divergence_nbody)

print(f"N-body divergence at 1846 (t=0):   {divergence_nbody[np.argmin(np.abs(years_since_1846))]:.1f}\u00b0")
idx_50 = np.argmin(np.abs(years_since_1846 - 50))
idx_100 = np.argmin(np.abs(years_since_1846 - 100))
idx_200 = np.argmin(np.abs(years_since_1846 - 200))
print(f"N-body divergence after 50 years:   {divergence_nbody[idx_50]:.1f}\u00b0")
print(f"N-body divergence after 100 years:  {divergence_nbody[idx_100]:.1f}\u00b0")
print(f"N-body divergence after 200 years:  {divergence_nbody[idx_200]:.1f}\u00b0")
N-body divergence at 1846 (t=0):   -0.3°
N-body divergence after 50 years:   -15.8°
N-body divergence after 100 years:  -49.9°
N-body divergence after 200 years:  -114.9°
Code
import matplotlib.pyplot as plt

mask = years_since_1846 >= 0


def _build(theme="light"):
    apply_style(theme)
    pal = palette(theme)
    fig, axes = plt.subplots(1, 2, figsize=(12, 5), sharey=True)

    # Two-body panel: use pal.after (reference/analytic)
    ax = axes[0]
    ax.plot(years_2body, divergence_2body, color=pal.after, linewidth=2)
    ax.axhline(0, color=pal.spine, linewidth=0.5)
    ax.axvline(0, color=pal.spine, linewidth=0.5, linestyle="--", alpha=0.3)
    ax.set_xlabel("Years after 1846")
    ax.set_ylabel("Predicted − true longitude (degrees)")
    ax.set_title("Two-body (Kepler)")
    ax.set_xlim(0, 200)

    # N-body panel: use pal.before (actual/observed divergence)
    ax = axes[1]
    ax.plot(years_since_1846[mask], divergence_nbody[mask], color=pal.before, linewidth=2)
    ax.axhline(0, color=pal.spine, linewidth=0.5)
    ax.set_xlabel("Years after 1846")
    ax.set_title("N-body (with Jupiter & Saturn)")
    ax.set_xlim(0, 200)

    return fig


display(dual_render(_build, alt="Le Verrier prediction degradation: two-body vs N-body longitude divergence"))
Figure 2: How Le Verrier’s predicted Neptune orbit diverges from reality. Left: simple two-body (Kepler) estimate. Right: full N-body simulation including Jupiter and Saturn perturbations.

Le Verrier’s prediction was tuned to match the 1846 sky position. The wrong orbital period means his predicted Neptune would have drifted away from the true Neptune within a few decades — a consequence of fitting the perturbation signal with an orbit that has the right phase but wrong frequency. The N-body curve does not start at zero in 1846: back-propagating both orbits to the 1781 epoch with Keplerian mean motions and re-integrating with Jupiter and Saturn re-introduces a small phase offset by 1846. The trend, not the intercept, is the point.

How Close Was He?

Code
import pandas as pd

def reciprocal_mass(value):
    return "—" if value is None else f"1/{1/value:.0f}"

# Several values are genuinely absent: the 1845 memoir published no orbit, and
# Galle's observation gave neither mass nor distance. Show every absent cell the
# same way.
def au(value):
    return "—" if value is None else f"{value:.3f}"


def deg(value):
    return "—" if value is None else f"{value:.1f}"

rows = [
    {
        "Source": LEVERRIER_MEMOIR_1845.source,
        "Semi-major axis (AU)": au(LEVERRIER_MEMOIR_1845.semi_major_axis_au),
        "Longitude (deg)": deg(LEVERRIER_MEMOIR_1845.longitude_deg),
        "Mass (1/M_sun)": reciprocal_mass(LEVERRIER_MEMOIR_1845.mass_solar),
    },
    {
        "Source": LEVERRIER_MEMOIR_1846_JUN.source,
        "Semi-major axis (AU)": au(LEVERRIER_MEMOIR_1846_JUN.semi_major_axis_au),
        "Longitude (deg)": deg(LEVERRIER_MEMOIR_1846_JUN.longitude_deg),
        "Mass (1/M_sun)": reciprocal_mass(LEVERRIER_MEMOIR_1846_JUN.mass_solar),
    },
    {
        "Source": LEVERRIER_MEMOIR_1846_AUG.source,
        "Semi-major axis (AU)": au(LEVERRIER_MEMOIR_1846_AUG.semi_major_axis_au),
        "Longitude (deg)": deg(LEVERRIER_MEMOIR_1846_AUG.longitude_deg),
        "Mass (1/M_sun)": reciprocal_mass(LEVERRIER_MEMOIR_1846_AUG.mass_solar),
    },
    {
        "Source": GALLE_OBSERVATION.source,
        "Semi-major axis (AU)": au(GALLE_OBSERVATION.semi_major_axis_au),
        "Longitude (deg)": deg(GALLE_OBSERVATION.longitude_deg),
        "Mass (1/M_sun)": reciprocal_mass(GALLE_OBSERVATION.mass_solar),
    },
    {
        "Source": MODERN_NEPTUNE.source,
        "Semi-major axis (AU)": au(MODERN_NEPTUNE.semi_major_axis_au),
        "Longitude (deg)": deg(MODERN_NEPTUNE.longitude_deg),
        "Mass (1/M_sun)": reciprocal_mass(MODERN_NEPTUNE.mass_solar),
    },
]

df = pd.DataFrame(rows)
df
Table 1: Neptune predictions and observations compared.
Source Semi-major axis (AU) Longitude (deg) Mass (1/M_sun)
0 Comptes Rendus vol 21, 10 Nov 1845
1 Comptes Rendus vol 22, 1 Jun 1846 325.0
2 Comptes Rendus vol 23, 31 Aug 1846 36.154 326.5 1/9300
3 Nichol, The Planet Neptune (1848), p. 89 327.4
4 Modern JPL Horizons / IAU 2009 30.069 1/19314

Later Career

After Neptune, Le Verrier was appointed director of the Paris Observatory in 1854. His tenure was productive but turbulent. His obituarist puts the break plainly: “In 1870, in consequence of differences with the staff of the Observatory, he ceased his connection with it for a time, but on the melancholy death of Delaunay in 1872, he was reinstated, and retained the management of the institution during the rest of his life.”

His later work focused on comprehensive planetary tables — painstaking computations of the orbits of all known planets, including the Mercury anomaly that would later require Einstein’s general relativity to explain (see the previous chapter).

Le Verrier died on 23 September 1877 — the 31st anniversary of Galle’s discovery of Neptune at the position Le Verrier had predicted.

References

  • Le Verrier, U. “Sur la planète qui produit les anomalies observées dans le mouvement d’Uranus.” Comptes Rendus 23 (31 Aug 1846).
  • Galle, J. G. “Account of the Discovery of the Planet of Le Verrier at Berlin.” Monthly Notices of the Royal Astronomical Society 7 (1846): 153.
  • Smart, W. M. “John Couch Adams and the Discovery of Neptune.” Occasional Notes of the Royal Astronomical Society 2 (1947): 33–55.
  • Grosser, M. The Discovery of Neptune (1962).
  • Standage, T. The Neptune File (2000).
  • Kollerstrom, N. “An Hiatus in History: The British Claim for Neptune’s Co-prediction, 1845–1846.” History of Science 44 (2006): 349–371.
  • Krajnović, D. “The contrivance of Neptune.” Astronomy & Geophysics 57 (2016), 5.28–5.34; arXiv:1610.06424 — reviews the archival re-examination after Airy’s Neptune file resurfaced in 1999, and gives the day-of-discovery longitudes compared above.
  • Herschel, J. F. W. “Address on the Award of the Testimonials.” Monthly Notices of the Royal Astronomical Society 8 (11 February 1848), 110–119 — the joint award to Le Verrier and Adams, and the Council’s explanation at p. 77 of the same volume.
  • The Record of the Royal Society of London, 3rd ed. (1912) — the Society’s own roll of Copley medallists, which runs Le Verrier, Herschel, Adams in successive years.
  • “Urbain Jean Joseph Le Verrier” (obituary notice). Monthly Notices of the Royal Astronomical Society 38 (1878), 155–166 — source of the quoted account of the 1870 break and the 1872 reinstatement.