In this post I'm going to show how to make scatter plots with team logos

In [10]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import NBAapi as nba
from scipy import misc
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import matplotlib.gridspec as gridspec
from PIL import Image
import StringIO
from cairosvg import svg2png

%matplotlib inline

The NBA team logos can be found on the NBA website. For example: http://stats.nba.com/media/img/teams/logos/season/2016-17/GSW_logo.svg To get all the logos we need to specify the season and the team abbreviation. To make it easier I added team info under nba.team.team_list(). The infromation is the full team name, abbreviation,team color, team id and conference. We can therefore merge any team stats with the team info to get the team abbreviation.

Note: if the sesaon is from 2002 or earlier, CHA needs to be changed to CHH

Plot logos:

Let's plot all of the NBA team logos from the 2016-17 season. I'm loading the logos from the nba website. You can play with the season to see how it works but note that before 2002 you'll have to change CHA to CHH in the team's abbreviation.

In [11]:
season = '2016-17'
teams = nba.team.team_list() # get team info
team_stats = nba.team.stats(season=season) # get team stats to see which teams played in the 2016-17 season
teams_wABB = team_stats.merge(teams,on='TEAM_NAME',how='left') # merge the DataFrames

names = teams_wABB['ABBREVIATION'].values # get list of teams abbreviations

# create the url parts that do not change
base_url = r'http://stats.nba.com/media/img/teams/logos/season/'
season = season
url_end = r'_logo.svg'

# use gridspec to create the subplots
plt.figure(figsize=(30,30))
gs1 = gridspec.GridSpec(6, 5)
gs1.update(wspace=0.01, hspace=0.01) # set the spacing between axes. 

for i,name in enumerate(names):
    ax1 = plt.subplot(gs1[i])
    I = svg2png(url=base_url + season + '//' +name + url_end) # convert svg to png strin
    Im = Image.open(StringIO.StringIO(I)) # convert png string to an image format
    ax1.imshow(Im) # plot image
    plt.gca().axis('off')
    

Now let's load some more interestign data!

Advanced team stats:

In [12]:
team_stats1 = nba.team.stats(season='2017-18',measuretype='Advanced') # get this year stats
team_stats2 = nba.team.stats(season='2016-17',measuretype='Advanced') # last year stats

# merge the DataFrames and add _2017 suffixes to the 2017 data
team_stats = team_stats1.merge(team_stats2,on='TEAM_ID',how = 'left',suffixes=('', '_2017')) 

# merge with team list to get the abbreviation, color and conference data
team_stats_w_names = team_stats.merge(teams,on='TEAM_NAME',how='left')

# get relevant data
conf = team_stats_w_names['conference'].values
DEF = team_stats_w_names['DEF_RATING'].values
OFF = team_stats_w_names['OFF_RATING'].values
DEF2 = team_stats_w_names['DEF_RATING_2017'].values
OFF2 = team_stats_w_names['OFF_RATING_2017'].values
names = team_stats_w_names['ABBREVIATION'].values
colors = team_stats_w_names['color'].values

Plotting the data:

I want to make a scatter plot but with the team logos instead of the typical plot. I found this great code on stack overflow: https://stackoverflow.com/questions/22566284/matplotlib-how-to-plot-images-instead-of-points I made slight changes but the bulk of the code is the same.

I'm going to write it as a function since I'm going to use it a few times. Also, I uploaded the 2016-17 team logos to the NBAapi package into the data folder which can be accessed with nba.DATA_PATH. I'm going to upload the images from the package but if a different year is used you might want to load the images from the web like the above example.

In [13]:
def scatter_plot_with_logos(X,Y,X2,Y2,names,colors):   
    artists = []
    f = nba.DATA_PATH
    for d,o,d2,o2,name,c in zip(X,Y,X2,Y2,names,colors):
        plt.plot(d2,o2,'o',color=c,markersize=16)
        plt.plot([d,d2],[o,o2],'--',color=c)
        im = misc.imread(f+name+'.png')
        im2 = OffsetImage(im, zoom=