Map Animation of UFC Events up to UFC 250 with MapBox

Technologies: D3.js, Javascript, MapBox API


Here I put together a map animation showing the various locations of UFC events that have taken place worldwide. From November 12, 1993 (UFC 1) to June 6, 2020 (UFC 250), there’s been a total of 518 events and UFC has visited 161 cities and 28 countries.


The list of past and scheduled UFC events were previously obtained from the UFC events Wikipedia page. I read them into a Pandas data frame and excluded events that were cancelled or postponed. Only events from UFC 1 to UFC 250 were included in the dataset.

events_df = pd.read_csv("data/list_of_UFC_past_events.csv")
scheduled_df = pd.read_csv("data/list_of_UFC_scheduled_events.csv")
events_df = events_df.append(scheduled_df, sort=True)
# Remove cancelled events
events_df = events_df[events_df['Attendance']!='Cancelled']
# Removed postponed events
events_df = events_df[events_df['Attendance']!='Postponed']

The names of the venues and cities for each event were extracted from the data.

city_df = events_df["Venue"] + ", " + events_df["Location"]
print("Number of visits to cities: " + str(len(city_df)))
city_df = city_df.unique()
print("Number of unique cities: " + str(len(city_df)))

I used the Geocoder from MapBox to get the longitude and latitude coordinates for the event locations. This required first obtaining a MapBox API access token from their website.

# Geocode the event locations
from mapbox import Geocoder
mapbox_access_token = "YOUR_ACCESS_CODE"
geocoder = Geocoder(access_token=mapbox_access_token)
geo_city_df = []
extract_geo_city_df = pd.DataFrame(columns=('location', 'relevance', 'place_name','lat','lng'))
for venue in city_df:
     response = geocoder.forward(venue)
     features = response.geojson()['features'][0]
     extract_geo_city_df = extract_geo_city_df.append({'location' : venue, 'relevance' : features['relevance'], 'place_name' : features['place_name'], 'lat' : features['geometry']['coordinates'][1], 'lng' : features['geometry']['coordinates'][0]} , ignore_index=True)

The Geocoder will try to search the location and return the coordinates along with a relevance score which provides an assessment of the accuracy of its search. The venue locations were mapped to its corresponding event.

     events_df['coords'] = events_df['Address'].map(geo_city_dict)
     events_df['lat'] = events_df['Address'].map(geo_city_dict_lat)
     events_df['lng'] = events_df['Address'].map(geo_city_dict_lng)

As an added feature, I decided to include the poster for each event. I gathered a list of links to each event’s poster image. The initial list consists of the poster images from the event Wikipedia page. For events that had missing posters or incorrect posters, I was able to locate the event poster from other sources via Google.

events_df = pd.concat([events_df, posters_df], axis=1)

Once all the data was compiled, I wrote the data frame to a csv file and used csv2geojson to convert the data to a geojson file.

csv2geojson events_with_posters_df.csv > events_df.geojson

Building the Animated Map

I used the following examples as references for constructing the animated map.

The timeline animation example served as a good starting point. It demonstrates how to load data from a geojson file and also how to update the map using a slider. The live update feature example utilizes the setInterval function which calls a reoccurring function every specified number of milliseconds. The popup example shows how to use the mapboxgl.Popup component to display information at specific coordinates on a map.

The resulting animated map can be found here and the full source code can be found in the project GitHub repository.

Here’s a video that uses the animated map.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.