How to Use the TMDB API to Find Films with the Highest Revenue
Tags: api, python, culture, webdev
Published: 2017-11-26 16:39:09

---
title: How to Use the TMDB API to Find Films with the Highest Revenue
description: A guide to using The Movie Database to programmatically get film information.
image: assets/images/GetOut.png
permalink: using-tmdb-api
author: monica_powell
tags: api, python, culture, webdev

published: true

---

![png](https://thepracticaldev.s3.amazonaws.com/i/9upyzrcahwh20chcrkf4.png)


_Get Out_ has been one of the most talked about films in 2017 and as of April 2017 <a href="http://www.thefader.com/2017/04/04/get-out-original-screenplay-record" target="_blank">the highest grossing debut film based on an original screenplay in history</a>. We want to programmatically find out how _Get Out_ ranked amongst other 2017 American films and which films have earned the most revenue in 2017. This tutorial assumes most readers have basic working knowledge of Python.

### Prequisites
- Install the following python packages and run them ideally in a <a href="http://python-guide-pt-br.readthedocs.io/en/latest/dev/virtualenvs/" target="_blank">virtualenv</a>.
    - config
    - requests
    - locale
    - pandas
    - matplotlib

- In addition to installing the above dependencies we will need to request an API key from [The Movie DB (TMDB)](https://www.themoviedb.org/). TMDB has a free API to programmatically access information about movies.

    - In order to request an API key from TMDB:
      1. <a href="https://www.themoviedb.org/account/signup" target="_blank">Create a free account</a>
      2. Check your e-mail to verify your account.
      3. Visit the <a href="https://www.themoviedb.org/settings/api" target="_blank">API Settings page</a> in your Account Settings and request an API key
      4. You should now have an API key and be ready to go!



```python
import config # to hide TMDB API keys
import requests # to make TMDB API calls
import locale # to format currency as USD
locale.setlocale( locale.LC_ALL, '' )

import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter # to format currency on charts axis

api_key = config.tmdb_api_key # get TMDB API key from config.py file
```

If you plan on committing your project to GitHub or another public repository and need help setting up `config` you should read [this article](https://medium.com/black-tech-diva/hide-your-api-keys-7635e181a06c) about using `config` to hide API keys.

## Part 1: Determine the highest earning American films of 2017

In this section we will request **2017** data from TMDB, store the data we recieve as a `json` into a `dataframe` and then use `matplotlib` to visualize our data.


### Make API Call to TMDB to return the data of interest
In order to get the highest earning films from TMDB an API request needs to be constructed to return films with a `primary_release_year` of 2017 sorted in descending order by revenue.


```python
response = requests.get('https://api.themoviedb.org/3/discover/movie?api_key=' +  api_key + '&primary_release_year=2017&sort_by=revenue.desc')
```


```python
highest_revenue = response.json() # store parsed json response

# uncomment the next line to get a peek at the highest_revenue json structure
# highest_revenue

highest_revenue_films = highest_revenue['results']
```

### Create dataframe from JSON returned from TMDB API call

Let's store the JSON data returned from our API call in a dataframe to store each film and its associated revenue.


```python
# define column names for our new dataframe
columns = ['film', 'revenue']

# create dataframe with film and revenue columns
df = pandas.DataFrame(columns=columns)
```

Now to add the data to our dataframe we will need to loop through the data.


```python
# for each of the highest revenue films make an api call for that specific movie to return the budget and revenue
for film in highest_revenue_films:
    # print(film['title'])
    film_revenue = requests.get('https://api.themoviedb.org/3/movie/'+ str(film['id']) +'?api_key='+ api_key+'&language=en-US')
    film_revenue = film_revenue.json()
    #print(locale.currency(film_revenue['revenue'], grouping=True ))
    df.loc[len(df)]=[film['title'],film_revenue['revenue']] # store title and revenue in our dataframe    
```

Below is what the dataframe `head` (top 5 lines) looks like after iterating through the films our API call returned.


```python
df.head()
```




<div>
<style>
    .dataframe thead tr:only-child th {
        text-align: right;
    }

    .dataframe thead th {
        text-align: left;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>film</th>
      <th>revenue</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Beauty and the Beast</td>
      <td>1221782049</td>
    </tr>
    <tr>
      <th>1</th>
      <td>The Fate of the Furious</td>
      <td>1212583865</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Guardians of the Galaxy Vol. 2</td>
      <td>744784722</td>
    </tr>
    <tr>
      <th>3</th>
      <td>Logan</td>
      <td>608674100</td>
    </tr>
    <tr>
      <th>4</th>
      <td>Kong: Skull Island</td>
      <td>565151307</td>
    </tr>
  </tbody>
</table>
</div>



### Let's actually _see_ the data with matplotlib

We will create a horizontal bar chart using matplotlib to display the revenue earned for each film.


```python
matplotlib.style.use('ggplot')
fig, ax = plt.subplots()
df.plot(kind="barh", y='revenue', color = ['#624ea7', '#599ad3', '#f9a65a', '#9e66ab', 'purple'], x=df['film'], ax=ax)

#format xaxis in terms of currency
formatter = FuncFormatter(currency)
ax.xaxis.set_major_formatter(formatter)
ax.legend().set_visible(False)

avg = df['revenue'].mean()

# Add a line for the average
ax.axvline(x=avg, color='b', label='Average', linestyle='--', linewidth=1)

ax.set(title='American Films with Highest Revenue (2017)', xlabel='Revenue', ylabel='Film')
```




    [<matplotlib.text.Text at 0x111f8aba8>,
     <matplotlib.text.Text at 0x111f20978>,
     <matplotlib.text.Text at 0x111fad2e8>]



![png](https://thepracticaldev.s3.amazonaws.com/i/vnxcfw9fjq4ohagxfovz.png)


## Part 2: Determine the highest earning American films of all-time

In this section we will request **all-time** data from TMDB, store the data we recieve as a `json` into a `dataframe` and then use `matplotlib` to visualize our data. Our API call will be similar to the one we used in the previous section but sans `&primary_release_year=2017`.

### Requesting, formatting and storing API data


```python
response = requests.get('https://api.themoviedb.org/3/discover/movie?api_key=' +  api_key + '&sort_by=revenue.desc')
highest_revenue_ever = response.json()
highest_revenue_films_ever = highest_revenue_ever['results']

columns = ['film', 'revenue', 'budget', 'release_date']
highest_revenue_ever_df = pandas.DataFrame(columns=columns)

for film in highest_revenue_films_ever:
    # print(film['title'])

    film_revenue = requests.get('https://api.themoviedb.org/3/movie/'+ str(film['id']) +'?api_key='+ api_key+'&language=en-US')
    film_revenue = film_revenue.json()
    # print(film_revenue)

    # print(locale.currency(film_revenue['revenue'], grouping=True ))

    # Lord of the Rings duplicate w/ bad data was being returned  https://www.themoviedb.org/movie/454499-the-lord-of-the-rings
    # It's budget was $281 which is way too low for a top-earning film. Therefore in order to be added to dataframe the film
    # budget must be greater than $281.

    if film_revenue['budget'] > 281:
        # print(film_revenue['budget'])
        # add film title, revenue, budget and release date to the dataframe
        highest_revenue_ever_df.loc[len(highest_revenue_ever_df)]=[film['title'],film_revenue['revenue'], (film_revenue['budget'] * -1), film_revenue['release_date']]

highest_revenue_ever_df.head()    

```




<div>
<style>
    .dataframe thead tr:only-child th {
        text-align: right;
    }

    .dataframe thead th {
        text-align: left;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>film</th>
      <th>revenue</th>
      <th>budget</th>
      <th>release_date</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Avatar</td>
      <td>2781505847</td>
      <td>-237000000</td>
      <td>2009-12-10</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Star Wars: The Force Awakens</td>
      <td>2068223624</td>
      <td>-245000000</td>
      <td>2015-12-15</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Titanic</td>
      <td>1845034188</td>
      <td>-200000000</td>
      <td>1997-11-18</td>
    </tr>
    <tr>
      <th>3</th>
      <td>The Avengers</td>
      <td>1519557910</td>
      <td>-220000000</td>
      <td>2012-04-25</td>
    </tr>
    <tr>
      <th>4</th>
      <td>Jurassic World</td>
      <td>1513528810</td>
      <td>-150000000</td>
      <td>2015-06-09</td>
    </tr>
  </tbody>
</table>
</div>



### Calculate the gross profit
We can calculate the gross profit by subtracting total revenue from amount spent. Earlier we made the budget values negative therefore we need to add the revenue to the (negative) budget to get the gross profit which is effectively subtraction.


```python
highest_revenue_ever_df['gross'] = highest_revenue_ever_df['revenue'] + highest_revenue_ever_df['budget']
```

What does the dataframe look like now?


```python
highest_revenue_ever_df.head()
```




<div>
<style>
    .dataframe thead tr:only-child th {
        text-align: right;
    }

    .dataframe thead th {
        text-align: left;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>film</th>
      <th>revenue</th>
      <th>budget</th>
      <th>release_date</th>
      <th>gross</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>Avatar</td>
      <td>2781505847</td>
      <td>-237000000</td>
      <td>2009-12-10</td>
      <td>2544505847</td>
    </tr>
    <tr>
      <th>1</th>
      <td>Star Wars: The Force Awakens</td>
      <td>2068223624</td>
      <td>-245000000</td>
      <td>2015-12-15</td>
      <td>1823223624</td>
    </tr>
    <tr>
      <th>2</th>
      <td>Titanic</td>
      <td>1845034188</td>
      <td>-200000000</td>
      <td>1997-11-18</td>
      <td>1645034188</td>
    </tr>
    <tr>
      <th>3</th>
      <td>The Avengers</td>
      <td>1519557910</td>
      <td>-220000000</td>
      <td>2012-04-25</td>
      <td>1299557910</td>
    </tr>
    <tr>
      <th>4</th>
      <td>Jurassic World</td>
      <td>1513528810</td>
      <td>-150000000</td>
      <td>2015-06-09</td>
      <td>1363528810</td>
    </tr>
  </tbody>
</table>
</div>



### Plotting data in matplotlib with horizontal bar charts and a scatter plot


```python
fig, ax = plt.subplots()
highest_revenue_ever_df.plot(kind="barh", y='revenue', color = ['#624ea7', '#599ad3', '#f9a65a', '#9e66ab', 'purple'], x=highest_revenue_ever_df['film'], ax=ax)
formatter = FuncFormatter(currency)
ax.xaxis.set_major_formatter(formatter)
ax.legend().set_visible(False)
ax.set(title='American Films with Highest Revenue (All Time)', xlabel='Revenue', ylabel='Film')
```




    [<matplotlib.text.Text at 0x111c90e48>,
     <matplotlib.text.Text at 0x111f85588>,
     <matplotlib.text.Text at 0x1120f0e48>]




![png](https://thepracticaldev.s3.amazonaws.com/i/4lk5dn0t37y6fuuod7u7.png)



```python
fig, ax = plt.subplots()
highest_revenue_ever_df.plot(kind="barh", y='gross', color = ['#624ea7', '#599ad3', '#f9a65a', '#9e66ab', 'purple'], x=highest_revenue_ever_df['film'], ax=ax)
formatter = FuncFormatter(currency)
ax.xaxis.set_major_formatter(formatter)
ax.legend().set_visible(False)
ax.set(title='Gross Profit of the American Films with Highest Revenue (All Time)', xlabel='Gross Profit', ylabel='Film')
```




    [<matplotlib.text.Text at 0x112285cf8>,
     <matplotlib.text.Text at 0x1120bf198>,
     <matplotlib.text.Text at 0x11234de10>]




![png](https://thepracticaldev.s3.amazonaws.com/i/5zgxk3bbojt5i2l81cv7.png)



```python
fig, ax = plt.subplots()
highest_revenue_ever_df.plot(kind='scatter', y='gross', x='budget', ax=ax)
formatter = FuncFormatter(currency)
ax.xaxis.set_major_formatter(formatter)
ax.yaxis.set_major_formatter(formatter)
ax.set(title='Profit vs Budget of the American Films with Highest Revenue (All Time)', xlabel='Budget', ylabel='Gross Profit')

```




    [<matplotlib.text.Text at 0x112b67f98>,
     <matplotlib.text.Text at 0x112b29518>,
     <matplotlib.text.Text at 0x112b8e550>]




![png](https://thepracticaldev.s3.amazonaws.com/i/fr1xwkvxa08ky9880ixi.png)



```python
# Adding release year to dataframe
# highest_revenue_ever_df['year'] = pd.DatetimeIndex(highest_revenue_ever_df['release_date']).year
# print(highest_revenue_ever_df)
```

### Limitations

The above data and graphs do not account for inflation (the TMDB API returns by revenue unadjusted by inflation) therefore the earnings from more recent films are more weighted than their earlier counterparts. When looking at _all time_ data inflation should be adjusted for however when looking over a shorter time period adjusting for inflation might not be necessary. Older films would appear above if inflation was taken into account, as it is now, the oldest film on this list was _The Titanic_ in 1997.

_Lead photo is Chris Washington, played by Daniel Kaluuya, from Get Out.   Universal Pictures_ 

_A version of this article was originally published by Monica Powell on [www.datalogues.com](http://www.datalogues.com/using-tmdb-api)_