{"id":1179,"date":"2024-06-06T07:00:13","date_gmt":"2024-06-06T12:00:13","guid":{"rendered":"https:\/\/wollen.org\/blog\/?p=1179"},"modified":"2025-03-03T14:50:39","modified_gmt":"2025-03-03T20:50:39","slug":"how-much-does-a-best-picture-award-cost","status":"publish","type":"post","link":"https:\/\/wollen.org\/blog\/2024\/06\/how-much-does-a-best-picture-award-cost\/","title":{"rendered":"How much does a Best Picture award cost?"},"content":{"rendered":"<p>This year <em>Oppenheimer<\/em> took home the <a href=\"https:\/\/www.oscars.org\/oscars\/ceremonies\/2024\" target=\"_blank\" rel=\"noopener\">Academy Awards&#8217; Oscar for Best Picture<\/a>. It was a somewhat unusual winner because the movie also performed exceptionally well at the box office. In recent years, the Best Picture category has favored more niche films with narrower appeal and, most relevant to this post, lower budgets.<\/p>\n<p>It&#8217;s an interesting narrative but what does the data show? I did a quick scrape of the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Academy_Award_for_Best_Picture\" target=\"_blank\" rel=\"noopener\">Best Picture Wikipedia page<\/a> for title and budget information. I managed to nail down the budget for all but one of the 96 winners\u2014<em>Going My Way<\/em> (1945). I&#8217;ll link the dataset at the bottom of this post.<\/p>\n<p>Of course the data is in nominal terms so we&#8217;ll have to adjust for inflation. To adjust prices we can use the U.S. Bureau of Labor Statistics&#8217; <a href=\"https:\/\/www.bls.gov\/cpi\/\" target=\"_blank\" rel=\"noopener\">Consumer Prince Index<\/a> (CPI). CPI tracks the value of goods and services and measures the value of a dollar at any point in time. We can use it to calculate that, for example, <em>The Godfather&#8217;s<\/em> $6.6 million budget in 1972 would be equivalent to nearly $50 million today. Let&#8217;s adjust all Best Picture budgets for inflation and see how they compare to <em>Oppenheimer<\/em>.<\/p>\n<hr \/>\n<h4>1. Prepare the data.<\/h4>\n<p>Start by installing the <a href=\"https:\/\/pypi.org\/project\/cpi\/1.0.0\/\" target=\"_blank\" rel=\"noopener\">cpi module<\/a>. Then read the dataset into a pandas DataFrame.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">import pandas as pd\r\nfrom cpi import inflate\r\nimport matplotlib.pyplot as plt\r\n\r\ndf = pd.read_csv(\"best_picture_data.csv\")<\/pre>\n<p>Columns include:<\/p>\n<ul>\n<li><strong>ceremony<\/strong> \u2014 Year of the Oscars Ceremony.<\/li>\n<li><strong>film<\/strong> \u2014 Title of the movie.<\/li>\n<li><strong>url<\/strong> \u2014 The Wikipedia URL.<\/li>\n<li><strong>budget<\/strong> \u2014 The movie&#8217;s nominal budget (not yet adjusted for inflation).<\/li>\n<\/ul>\n<p>Using <code>cpi.inflate()<\/code> is very straightforward. We can <code>apply<\/code> the function to a new column and pass three arguments:<\/p>\n<ol>\n<li>Budget.<\/li>\n<li>Year of the ceremony minus one, because generally the Oscars consider movies from the previous year.<\/li>\n<li>The target year, 2023. We want to inflate dollars to match <em>Oppenheimer&#8217;s<\/em> release year.<\/li>\n<\/ol>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df.loc[:, 'budget_cpi'] = df.apply(lambda row: inflate(row['budget'], row['ceremony'] - 1, 2023), axis=1)<\/pre>\n<p>At this point we have everything we need to create a bar graph. But I&#8217;d also like to plot a five-year moving average to help smooth out the data.<\/p>\n<p>pandas Series types, i.e. columns, have a <code>rolling()<\/code> method that can generate a moving average. The <code>window<\/code> parameter will be 5 because at any point we want to know the average of the most recent five budgets. Since one row is missing data, we set <code>min_periods<\/code> to 4, which will accept four data points when necessary and avoid a discontinuity in the line.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">df['budget_cpi_5year'] = df['budget_cpi'].rolling(window=5, min_periods=4).mean()<\/pre>\n<hr \/>\n<h4>2. Plot the data.<\/h4>\n<p>I&#8217;ll use a custom mplstyle for this plot. It will be linked along with the dataset at the bottom of this post.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">plt.style.use(\"oscars.mplstyle\")\r\nfig, ax = plt.subplots()<\/pre>\n<p>Plot the relevant columns\u2014budget as a bar plot and moving average as a line.<\/p>\n<p>One small detail in the moving average plot should be corrected. Set it to start with the fifth value <code>[4:]<\/code>. Because we adjusted <code>min_periods<\/code> above, pandas begins calculating a moving average with the fourth value. It wouldn&#8217;t make sense for a five-year average to appear before the fifth value is known.<\/p>\n<p>Pass <code>zorder<\/code> arguments to set layer order, line above bar.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">ax.bar(df['ceremony'], df['budget_cpi'], zorder=1)\r\n\r\nax.plot(df['ceremony'][4:], df['budget_cpi_5year'][4:], color=\"#DDDDDD\", label=\"5-Year Average\", zorder=2)<\/pre>\n<p>Next configure x-ticks and y-ticks. I like to define window limits explicitly so I can use those variables later to place text on the plot.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">x_ticks = range(1925, 2030, 5)\r\nax.set_xticks(x_ticks)\r\nx_left, x_right = 1923.5, 2026.5\r\nax.set_xlim(x_left, x_right)\r\nplt.setp(ax.xaxis.get_majorticklabels(), rotation=60, ha=\"right\", rotation_mode=\"anchor\")\r\n\r\ny_ticks = range(0, 450000000, 50000000)\r\nax.set_yticks(y_ticks)\r\ny_tick_labels = [f\"${n \/ 1000000:.0f}M\" for n in y_ticks]\r\nax.set_yticklabels(y_tick_labels)\r\ny_bottom, y_top = 0, y_ticks[-1] * 1.01\r\nax.set_ylim(y_bottom, y_top)<\/pre>\n<p>Create a legend to communicate what the moving average represents.<\/p>\n<p>Set a title and any necessary axis labels. I usually don&#8217;t set an x-axis label when working with dates. Since the y-axis label is written sideways, I sometimes like to put an extra space between words to make it more readable.<\/p>\n<p>It&#8217;s also good to make a note of how exactly we adjust for inflation. There are many inflation calculators other than CPI. Notice how we use previously defined variables (e.g. <code>x_left<\/code>) to locate the text.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">ax.set_ylabel(\"Budget  (2023 Dollars)\")\r\n\r\nax.set_title(\"Academy Awards  \u2022  Best Picture Winner  \u2022  Budget  \u2022  Inflation Adjusted\")\r\n\r\nax.legend(loc=\"upper left\", labelcolor=\"#EEEEEE\")\r\n\r\nx_span = x_right - x_left\r\ny_span = y_top - y_bottom\r\nax.text(x_right - x_span * 0.005, y_ticks[-1] - y_span * 0.005,\r\n        \"Values adjusted using CPI inflation data.\",\r\n        size=9, ha=\"right\", va=\"top\")<\/pre>\n<p>I think when viewers see this plot they will immediately try to guess which bars represent which movies. It would make the plot more interesting to annotate the most noteworthy films. I picked a few outliers, like <em>Gone with the Wind<\/em> (1940). And winners that signaled a changing trend, like <em>Forrest Gump<\/em> (1995).<\/p>\n<p><code>highlight_coords<\/code> is a list of tuples containing title, x- and y-positions, and text alignment. I use a nested for-loop to iterate through both this list and the DataFrame. At each match, I call <code>annotate()<\/code> to place text and an arrow on the plot. You might call this plot <em>excessively annotated<\/em> and you wouldn&#8217;t necessarily be wrong. I still think it&#8217;s fun to see all the movie titles.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">highlight_coords = [(\"Gone with the Wind\", 1938, 125, \"center\"),\r\n                    (\"Ben-Hur\", 1959, 195, \"right\"),\r\n                    (\"Lawrence of Arabia\", 1963, 230, \"center\"),\r\n                    (\"My Fair Lady\", 1965, 200, \"left\"),\r\n                    (\"Forrest Gump\", 1993, 135, \"right\"),\r\n                    (\"Braveheart\", 1995, 175, \"right\"),\r\n                    (\"Titanic\", 1996, 388, \"right\"),\r\n                    (\"Gladiator\", 2000, 240, \"left\"),\r\n                    (\"LOTR: Return of the King\", 2003, 205, \"left\"),\r\n                    (\"The Departed\", 2008, 170, \"left\"),\r\n                    (\"Argo\", 2013, 95, \"center\"),\r\n                    (\"Oppenheimer\", 2024, 140, \"right\")]\r\n\r\nfor text, x_pos, y_pos, align in highlight_coords:\r\n    for r, row in df.iterrows():\r\n        if row['film'] == text:\r\n            ax.annotate(row['film'], ha=align, size=10,\r\n                        xy=(row['ceremony'], row['budget_cpi'] + y_span * 0.008), xytext=(x_pos, y_pos * 1e6),\r\n                        arrowprops={\"arrowstyle\": \"wedge\", \"color\": \"#EEEEEE\"})<\/pre>\n<p>Finally, save the figure.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\">plt.savefig(\"best_picture_budget.png\", dpi=150)<\/pre>\n<hr \/>\n<h4>3. The output.<\/h4>\n<p><a href=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-2222 size-full\" src=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget.png\" alt=\"\" width=\"2400\" height=\"975\" srcset=\"https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget.png 2400w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget-300x122.png 300w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget-1024x416.png 1024w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget-768x312.png 768w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget-1536x624.png 1536w, https:\/\/wollen.org\/blog\/wp-content\/uploads\/2024\/06\/best_picture_budget-2048x832.png 2048w\" sizes=\"auto, (max-width: 2400px) 100vw, 2400px\" \/><\/a><\/p>\n<p>The data confirms that <em>Oppenheimer<\/em> was a major break from the norm. Its $100 million budget doesn&#8217;t reach the heights of the 1990s and 2000s, but it is the most expensive Best Picture winner in 17 years. It was a rare intersection of blockbuster filmmaking and critical praise.<\/p>\n<p>I&#8217;m not sure what to make of the peak centered around <em>Titanic<\/em>. It could reflect a tendency toward excess in the post-Cold-War, high-growth, <a href=\"https:\/\/en.wikipedia.org\/wiki\/End_of_history\" target=\"_blank\" rel=\"noopener\">end of history<\/a> 90s. I&#8217;m tempted to read the 2008\u20132023 small-budget era as a post-Great-Recession attitude shift. Maybe Academy voters wanted to project frugality and distance themselves from broadly popular spectacles like <em>The Departed<\/em>. Or maybe a new generation of voters who value more &#8220;serious&#8221; films replaced an older one. I would guess it&#8217;s a combination of factors, given how strong the trend has been.<\/p>\n<p>We&#8217;ll have to wait and see if <em>Oppenheimer<\/em> ushers in a new era of higher-budget Best Picture success, or if it remains an exception to the rule.<\/p>\n<hr \/>\n<p><a href=\"https:\/\/wollen.org\/misc\/oscars_best-picture_2024.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\nfrom cpi import inflate\r\nimport matplotlib.pyplot as plt\r\n\r\n\r\ndf = pd.read_csv(\"best_picture_data.csv\")\r\n\r\ndf.loc[:, 'budget_cpi'] = df.apply(lambda row: inflate(row['budget'], row['ceremony'] - 1, 2023), axis=1)\r\n\r\ndf['budget_cpi_5year'] = df['budget_cpi'].rolling(window=5, min_periods=4).mean()\r\n\r\nplt.style.use(\"oscars.mplstyle\")\r\nfig, ax = plt.subplots()\r\n\r\nax.bar(df['ceremony'], df['budget_cpi'], zorder=1)\r\nax.plot(df['ceremony'][4:], df['budget_cpi_5year'][4:], color=\"#DDDDDD\", label=\"5-Year Average\", zorder=2)\r\n\r\nx_ticks = range(1925, 2030, 5)\r\nax.set_xticks(x_ticks)\r\nx_left, x_right = 1923.5, 2026.5\r\nax.set_xlim(x_left, x_right)\r\nplt.setp(ax.xaxis.get_majorticklabels(), rotation=60, ha=\"right\", rotation_mode=\"anchor\")\r\n\r\ny_ticks = range(0, 450000000, 50000000)\r\nax.set_yticks(y_ticks)\r\ny_tick_labels = [f\"${n \/ 1000000:.0f}M\" for n in y_ticks]\r\nax.set_yticklabels(y_tick_labels)\r\ny_bottom, y_top = 0, y_ticks[-1] * 1.01\r\nax.set_ylim(y_bottom, y_top)\r\n\r\nax.set_ylabel(\"Budget  (2023 Dollars)\")\r\n\r\nax.set_title(\"Academy Awards  \u2022  Best Picture Winner  \u2022  Budget  \u2022  Inflation Adjusted\")\r\n\r\nax.legend(loc=\"upper left\", labelcolor=\"#EEEEEE\")\r\n\r\nx_span = x_right - x_left\r\ny_span = y_top - y_bottom\r\nax.text(x_right - x_span * 0.005, y_ticks[-1] - y_span * 0.005,\r\n        \"Values adjusted using CPI inflation data.\",\r\n        size=9, ha=\"right\", va=\"top\")\r\n\r\nhighlight_coords = [(\"Gone with the Wind\", 1938, 125, \"center\"),\r\n                    (\"Ben-Hur\", 1959, 195, \"right\"),\r\n                    (\"Lawrence of Arabia\", 1963, 230, \"center\"),\r\n                    (\"My Fair Lady\", 1965, 200, \"left\"),\r\n                    (\"Forrest Gump\", 1993, 135, \"right\"),\r\n                    (\"Braveheart\", 1995, 175, \"right\"),\r\n                    (\"Titanic\", 1996, 388, \"right\"),\r\n                    (\"Gladiator\", 2000, 240, \"left\"),\r\n                    (\"LOTR: Return of the King\", 2003, 205, \"left\"),\r\n                    (\"The Departed\", 2008, 170, \"left\"),\r\n                    (\"Argo\", 2013, 95, \"center\"),\r\n                    (\"Oppenheimer\", 2024, 140, \"right\")]\r\n\r\nfor text, x_pos, y_pos, align in highlight_coords:\r\n    for r, row in df.iterrows():\r\n        if row['film'] == text:\r\n            ax.annotate(row['film'], ha=align, size=10,\r\n                        xy=(row['ceremony'], row['budget_cpi'] + y_span * 0.008), xytext=(x_pos, y_pos * 1e6),\r\n                        arrowprops={\"arrowstyle\": \"wedge\", \"color\": \"#EEEEEE\"})\r\n\r\nplt.savefig(\"best_picture_budget.png\", dpi=150)\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This year Oppenheimer took home the Academy Awards&#8217; Oscar for Best Picture. It was a somewhat unusual winner because the movie also performed exceptionally well at the box office. In recent years, the Best Picture category has favored more niche<\/p>\n","protected":false},"author":1,"featured_media":1204,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[239],"tags":[257,267,268,258,269,264,260,261,262,135,22,122,263,24,235,126,259,256,30,25,265,266],"class_list":["post-1179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-entertainment","tag-academy-awards","tag-annotate","tag-arrowprops","tag-awards","tag-best-picture","tag-budget","tag-christopher-nolan","tag-cillian-murphy","tag-cpi","tag-csv","tag-data","tag-dataset","tag-inflation","tag-matplotlib","tag-movies","tag-mplstyle","tag-oppenheimer","tag-oscars","tag-pandas","tag-python","tag-revenue","tag-rolling"],"_links":{"self":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/1179","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=1179"}],"version-history":[{"count":33,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/1179\/revisions"}],"predecessor-version":[{"id":2223,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/posts\/1179\/revisions\/2223"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/media\/1204"}],"wp:attachment":[{"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/media?parent=1179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/categories?post=1179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wollen.org\/blog\/wp-json\/wp\/v2\/tags?post=1179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}