{"id":1110,"date":"2024-03-20T07:00:14","date_gmt":"2024-03-20T12:00:14","guid":{"rendered":"https:\/\/wollen.org\/blog\/?p=1110"},"modified":"2025-03-03T18:37:31","modified_gmt":"2025-03-04T00:37:31","slug":"how-old-is-james-bond","status":"publish","type":"post","link":"https:\/\/wollen.org\/blog\/2024\/03\/how-old-is-james-bond\/","title":{"rendered":"How old is James Bond?"},"content":{"rendered":"<p>We&#8217;ve been hearing the Aaron Taylor-Johnson rumors for years. And if recent reports are true, he&#8217;s all but officially confirmed as the next James Bond star.<\/p>\n<p>At the time of this post, prediction market <a href=\"https:\/\/polymarket.com\/\" target=\"_blank\" rel=\"noopener\">Polymarket<\/a> 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&#8217;m not here to handicap the race.<\/p>\n<p>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?<\/p>\n<figure id=\"attachment_1849\" aria-describedby=\"caption-attachment-1849\" style=\"width: 450px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/ATJ_bullet-train2.gif\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1849 size-full\" src=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/ATJ_bullet-train2.gif\" alt=\"\" width=\"450\" height=\"187\" \/><\/a><figcaption id=\"caption-attachment-1849\" class=\"wp-caption-text\">Aaron Taylor-Johnson in <em>Bullet Train<\/em> (2022).<\/figcaption><\/figure>\n<hr \/>\n<h4>1. Prepare the data.<\/h4>\n<p>I scraped the <a href=\"https:\/\/en.wikipedia.org\/wiki\/List_of_James_Bond_films\" target=\"_blank\" rel=\"noopener\"><em>List of James Bond Films<\/em><\/a> 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.<\/p>\n<p>First, load the data into a pandas DataFrame.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pandas as pd\r\nimport matplotlib.pyplot as plt\r\nfrom matplotlib.dates import DateFormatter\r\n\r\ndf = pd.read_csv(\"bond_data.csv\", parse_dates=[\"date\"])<\/pre>\n<p>We know movie release dates but we&#8217;re <em>really<\/em> interested in the starring actor&#8217;s age on that day. We can use each actor&#8217;s birthday to create an <em>age<\/em> column.<\/p>\n<p>Granted, this isn&#8217;t a perfect way to calculate a time delta in units of years. Dividing days by 365.25 won&#8217;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&#8217;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&#8217;t reflect their exact on-screen age. But if movies can bend the truth then so can we. <code>apply<\/code> a function along the horizontal axis.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">birthday_dict = {\"Sean Connery\": \"August 25, 1930\",\r\n                 \"George Lazenby\": \"September 5, 1939\",\r\n                 \"Roger Moore\": \"October 14, 1927\",\r\n                 \"Timothy Dalton\": \"March 21, 1946\",\r\n                 \"Pierce Brosnan\": \"May 16, 1953\",\r\n                 \"Daniel Craig\": \"March 2, 1968\"}\r\n\r\ndf.loc[:, 'age_at_release'] = df.apply(lambda row: (row['date'] - pd.Timestamp(birthday_dict[row['actor']])).days \/ 365.25, axis=1)<\/pre>\n<p>At this point the DataFrame&#8217;s <code>head()<\/code> looks like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">        date                  title         actor  age_at_release\r\n0 1962-10-05                 Dr. No  Sean Connery       32.112252\r\n1 1963-10-10  From Russia with Love  Sean Connery       33.125257\r\n2 1964-09-17             Goldfinger  Sean Connery       34.064339\r\n3 1965-12-09            Thunderball  Sean Connery       35.290897\r\n4 1967-06-12    You Only Live Twice  Sean Connery       36.796715<\/pre>\n<hr \/>\n<h4>2. Plot the data.<\/h4>\n<p>I&#8217;m using a custom Matplotlib style that&#8217;s a forked version of the built-in <em>ggplot<\/em> style, which in turn is a play on <a href=\"https:\/\/ggplot2.tidyverse.org\/\" target=\"_blank\" rel=\"noopener\">R&#8217;s ggplot2<\/a>. You can download it at the bottom of this post.<\/p>\n<p>The general idea is to plot a line showing Bond&#8217;s age over time, including discontinuities when he&#8217;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 <code>zorder<\/code>.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">plt.style.use(\"wollen_ggplot.mplstyle\")\r\nfig, ax = plt.subplots()\r\n\r\nax.plot(df['date'], df['age_at_release'], color=\"black\", linewidth=0.6, zorder=1)<\/pre>\n<p>For the scatter plot, we&#8217;ll loop through each actor and use their name to create a DataFrame <em>view<\/em>, i.e. a subset of rows. For example, Pierce Brosnan starred in four Bond films, so <code>df2<\/code> will have four rows and <code>ax.scatter()<\/code> will add four markers to the figure. Set <code>zorder<\/code> to 2 so markers are drawn on the topmost layer.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">for name in df['actor'].unique():\r\n    df2 = df.copy()\r\n    df2 = df2[df2['actor'] == name]\r\n    ax.scatter(df2['date'], df2['age_at_release'], label=name, zorder=2)<\/pre>\n<p>At this point we&#8217;ve plotted the data and it&#8217;s a matter of final adjustments.<\/p>\n<p>A handy way to create a series of x-axis datetime values is to use <code>pd.date_range<\/code>. The &#8220;5YS&#8221; argument passed to <code>freq<\/code> requests a value every five years located at <strong>Y<\/strong>ear <strong>S<\/strong>tart (January 1st).<\/p>\n<p>I leave a little extra room above the top y-tick for a legend.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">x_ticks = pd.date_range(pd.Timestamp(\"Jan 1 1960\"), pd.Timestamp(\"Jan 1 2025\"), freq=\"5YS\")\r\nax.set_xticks(x_ticks)\r\nax.xaxis.set_major_formatter(DateFormatter(\"%Y\"))\r\nax.set_xlim(pd.Timestamp(\"July 1 1958\"), pd.Timestamp(\"July 1 2026\"))\r\n\r\ny_ticks = range(0, 65, 5)\r\nax.set_yticks(y_ticks)\r\nax.set_ylim(0, 64)\r\nax.set_ylabel(\"Age at Release  (Years)\")<\/pre>\n<p>In defining a legend, <code>ncol<\/code> refers to number of columns. I want the legend to be a single row at the top of the axis.<\/p>\n<p>Finally, set a title and save the figure. I bump <code>dpi<\/code> slightly to improve readability.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">ax.legend(loc=\"upper center\", ncol=6)\r\n\r\nax.set_title(\"James Bond Actors  |  Age\")\r\n\r\nplt.savefig(\"bond_actor_age.png\", dpi=120)<\/pre>\n<hr \/>\n<h4>3. The output.<\/h4>\n<p><a href=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/bond_actor_age.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-2228 size-full\" src=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/bond_actor_age.png\" alt=\"\" width=\"1440\" height=\"780\" srcset=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/bond_actor_age.png 1440w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/bond_actor_age-300x163.png 300w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/bond_actor_age-1024x555.png 1024w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/03\/bond_actor_age-768x416.png 768w\" sizes=\"auto, (max-width: 1440px) 100vw, 1440px\" \/><\/a><\/p>\n<p>Bond has ranged from 30 to 57 years old with an average of 43.9. The most age-representative Bond was Timothy Dalton in <em>License to Kill<\/em> (1989), who was a couple months past his 43rd birthday.<\/p>\n<p>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&#8217;s debut in <em>Casino Royale<\/em> (2006).<\/p>\n<p>So it&#8217;s not surprising that we&#8217;re hearing buzz about this particular actor right now. The data shows that he would be a great fit.<\/p>\n<hr \/>\n<p><a href=\"http:\/\/wollen.org\/misc\/bond_data_march2024.zip\"><strong>Download the data.<\/strong><\/a><\/p>\n<p><strong>Full code:<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pandas as pd\r\nimport matplotlib.pyplot as plt\r\nfrom matplotlib.dates import DateFormatter\r\n\r\n\r\ndf = pd.read_csv(\"bond_data.csv\", parse_dates=[\"date\"])\r\n\r\nbirthday_dict = {\"Sean Connery\": \"August 25, 1930\",\r\n                 \"George Lazenby\": \"September 5, 1939\",\r\n                 \"Roger Moore\": \"October 14, 1927\",\r\n                 \"Timothy Dalton\": \"March 21, 1946\",\r\n                 \"Pierce Brosnan\": \"May 16, 1953\",\r\n                 \"Daniel Craig\": \"March 2, 1968\"}\r\n\r\ndf.loc[:, 'age_at_release'] = df.apply(lambda row: (row['date'] - pd.Timestamp(birthday_dict[row['actor']])).days \/ 365.25, axis=1)\r\n\r\nplt.style.use(\"wollen_ggplot.mplstyle\")\r\nfig, ax = plt.subplots()\r\n\r\nax.plot(df['date'], df['age_at_release'], color=\"black\", linewidth=0.6, zorder=1)\r\n\r\nfor name in df['actor'].unique():\r\n    df2 = df.copy()\r\n    df2 = df2[df2['actor'] == name]\r\n    ax.scatter(df2['date'], df2['age_at_release'], label=name, zorder=2)\r\n\r\nx_ticks = pd.date_range(pd.Timestamp(\"Jan 1 1960\"), pd.Timestamp(\"Jan 1 2025\"), freq=\"5YS\")\r\nax.set_xticks(x_ticks)\r\nax.xaxis.set_major_formatter(DateFormatter(\"%Y\"))\r\nax.set_xlim(pd.Timestamp(\"July 1 1958\"), pd.Timestamp(\"July 1 2026\"))\r\n\r\ny_ticks = range(0, 65, 5)\r\nax.set_yticks(y_ticks)\r\nax.set_ylim(0, 64)\r\nax.set_ylabel(\"Age at Release  (Years)\")\r\n\r\nax.legend(loc=\"upper center\", ncol=6)\r\n\r\nax.set_title(\"James Bond Actors  |  Age\")\r\n\r\nplt.savefig(\"bond_actor_age.png\", dpi=120)<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;ve been hearing the Aaron Taylor-Johnson rumors for years. And if recent reports are true, he&#8217;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<\/p>\n","protected":false},"author":1,"featured_media":1133,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[239],"tags":[227,223,135,234,22,53,237,230,224,24,228,236,235,126,30,226,233,46,25,225,231,229,54,232],"class_list":["post-1110","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-entertainment","tag-aaron-taylor-johnson","tag-bond","tag-csv","tag-daniel-craig","tag-data","tag-datetime","tag-film","tag-george-lazenby","tag-james-bond","tag-matplotlib","tag-mgm","tag-movie","tag-movies","tag-mplstyle","tag-pandas","tag-pd-date_range","tag-pierce-brosnan","tag-plot","tag-python","tag-read_csv","tag-roger-moore","tag-sean-connery","tag-timestamp","tag-timothy-dalton"],"_links":{"self":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/1110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/comments?post=1110"}],"version-history":[{"count":35,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/1110\/revisions"}],"predecessor-version":[{"id":2229,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/1110\/revisions\/2229"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/media\/1133"}],"wp:attachment":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/media?parent=1110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/categories?post=1110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/tags?post=1110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}