In this post I'm going to show how to make scatter plots with team logos
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
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.
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')
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.
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=