Entertainment

How old is James Bond?

We’ve been hearing the Aaron Taylor-Johnson rumors for years. And if recent reports are true, he’s all but officially confirmed as the next James Bond star.

At the time of this post, prediction market Polymarket lists Taylor-Johnson as having an 83% chance to become the next Bond. I would say those odds still seem a bit long but I’m not here to handicap the race.

What I want to do is put the casting in context. How old would Taylor-Johnson be when his first movie premieres and how would that compare to previous Bond actors?

Aaron Taylor-Johnson in Bullet Train (2022).

1. Prepare the data.

I scraped the List of James Bond Films Wikipedia page and dumped the data into a CSV file. Columns include movie release date, film title, and starring actor. You can download the dataset at the bottom of this post.

First, load the data into a pandas DataFrame.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter

df = pd.read_csv("bond_data.csv", parse_dates=["date"])

We know movie release dates but we’re really interested in the starring actor’s age on that day. We can use each actor’s birthday to create an age column.

Granted, this isn’t a perfect way to calculate a time delta in units of years. Dividing days by 365.25 won’t account for leap year exceptions on the century, or exceptions to the exceptions on millennia, or leap seconds, or relativistic time travel effects. But fortunately there won’t be enough pixels in our image for that to be a issue. And, of course, movies are filmed some time in advance of release, so this value won’t reflect their exact on-screen age. But if movies can bend the truth then so can we. apply a function along the horizontal axis.

birthday_dict = {"Sean Connery": "August 25, 1930",
                 "George Lazenby": "September 5, 1939",
                 "Roger Moore": "October 14, 1927",
                 "Timothy Dalton": "March 21, 1946",
                 "Pierce Brosnan": "May 16, 1953",
                 "Daniel Craig": "March 2, 1968"}

df.loc[:, 'age_at_release'] = df.apply(lambda row: (row['date'] - pd.Timestamp(birthday_dict[row['actor']])).days / 365.25, axis=1)

At this point the DataFrame’s head() looks like this:

        date                  title         actor  age_at_release
0 1962-10-05                 Dr. No  Sean Connery       32.112252
1 1963-10-10  From Russia with Love  Sean Connery       33.125257
2 1964-09-17             Goldfinger  Sean Connery       34.064339
3 1965-12-09            Thunderball  Sean Connery       35.290897
4 1967-06-12    You Only Live Twice  Sean Connery       36.796715

2. Plot the data.

I’m using a custom Matplotlib style that’s a forked version of the built-in ggplot style, which in turn is a play on R’s ggplot2. You can download it at the bottom of this post.

The general idea is to plot a line showing Bond’s age over time, including discontinuities when he’s re-cast, and overlay markers on the line to represent each movie in the series. Since we want the scatter plot to be layered above the line, we pass a layer argument to zorder.

plt.style.use("wollen_ggplot.mplstyle")
fig, ax = plt.subplots()

ax.plot(df['date'], df['age_at_release'], color="black", linewidth=0.6, zorder=1)

For the scatter plot, we’ll loop through each actor and use their name to create a DataFrame view, i.e. a subset of rows. For example, Pierce Brosnan starred in four Bond films, so df2 will have four rows and ax.scatter() will add four markers to the figure. Set zorder to 2 so markers are drawn on the topmost layer.

for name in df['actor'].unique():
    df2 = df.copy()
    df2 = df2[df2['actor'] == name]
    ax.scatter(df2['date'], df2['age_at_release'], label=name, zorder=2)

At this point we’ve plotted the data and it’s a matter of final adjustments.

A handy way to create a series of x-axis datetime values is to use pd.date_range. The “5YS” argument passed to freq requests a value every five years located at Year Start (January 1st).

I leave a little extra room above the top y-tick for a legend.

x_ticks = pd.date_range(pd.Timestamp("Jan 1 1960"), pd.Timestamp("Jan 1 2025"), freq="5YS")
ax.set_xticks(x_ticks)
ax.xaxis.set_major_formatter(DateFormatter("%Y"))
ax.set_xlim(pd.Timestamp("July 1 1958"), pd.Timestamp("July 1 2026"))

y_ticks = range(0, 65, 5)
ax.set_yticks(y_ticks)
ax.set_ylim(0, 64)
ax.set_ylabel("Age at Release  (Years)")

In defining a legend, ncol refers to number of columns. I want the legend to be a single row at the top of the axis.

Finally, set a title and save the figure. I bump dpi slightly to improve readability.

ax.legend(loc="upper center", ncol=6)

ax.set_title("James Bond Actors  |  Age")

plt.savefig("bond_actor_age.png", dpi=120)

3. The output.

Bond has ranged from 30 to 57 years old with an average of 43.9. The most age-representative Bond was Timothy Dalton in License to Kill (1989), who was a couple months past his 43rd birthday.

Aaron Taylor-Johnson was born in June 1990. If MGM began production later this year (admittedly an optimistic assumption) then we might roughly estimate his first Bond film would premiere around his 38th birthday. That would be a nearly identical timeline to Daniel Craig’s debut in Casino Royale (2006).

So it’s not surprising that we’re hearing buzz about this particular actor right now. The data shows that he would be a great fit.


Download the data.

Full code:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter


df = pd.read_csv("bond_data.csv", parse_dates=["date"])

birthday_dict = {"Sean Connery": "August 25, 1930",
                 "George Lazenby": "September 5, 1939",
                 "Roger Moore": "October 14, 1927",
                 "Timothy Dalton": "March 21, 1946",
                 "Pierce Brosnan": "May 16, 1953",
                 "Daniel Craig": "March 2, 1968"}

df.loc[:, 'age_at_release'] = df.apply(lambda row: (row['date'] - pd.Timestamp(birthday_dict[row['actor']])).days / 365.25, axis=1)

plt.style.use("wollen_ggplot.mplstyle")
fig, ax = plt.subplots()

ax.plot(df['date'], df['age_at_release'], color="black", linewidth=0.6, zorder=1)

for name in df['actor'].unique():
    df2 = df.copy()
    df2 = df2[df2['actor'] == name]
    ax.scatter(df2['date'], df2['age_at_release'], label=name, zorder=2)

x_ticks = pd.date_range(pd.Timestamp("Jan 1 1960"), pd.Timestamp("Jan 1 2025"), freq="5YS")
ax.set_xticks(x_ticks)
ax.xaxis.set_major_formatter(DateFormatter("%Y"))
ax.set_xlim(pd.Timestamp("July 1 1958"), pd.Timestamp("July 1 2026"))

y_ticks = range(0, 65, 5)
ax.set_yticks(y_ticks)
ax.set_ylim(0, 64)
ax.set_ylabel("Age at Release  (Years)")

ax.legend(loc="upper center", ncol=6)

ax.set_title("James Bond Actors  |  Age")

plt.savefig("bond_actor_age.png", dpi=120)