NBA Free Throws

These visuals explore NBA free throws from the year 2006 to 2016.They take a look at when free throws get taken during a game, what season they were taken the most and what period is the player with the most free throws taking free throws. The dataset includes 11 columns including result, game, period, player and more.


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.ticker import FuncFormatter as ff

path = "C:/Users/AkiMa/Downloads/"
filename  = path +  "free_throws.csv"

comma_fmt = ff(lambda x, p: format(int(x), ','))


df = pd.read_csv(filename)

Total Free Throws Per quarter

This line graph shows the total number of free throws per quarter out of all the players in the NBA. It is evident that period 4 experiences the highest quantity of free throws while the over-time periods have significantly less. In the regular time periods, we can see a steady increase in number of free throws from period 1 to period 2, and then a plateau from period 2 to 3, ending with an increase at period 4 with 175,000 free throws.

PeriodCount = pd.DataFrame(df['period'].value_counts().reset_index(name='count'))

PeriodCount = PeriodCount.sort_values(by=['index'])

# Create Plot
plt.figure(figsize=(18,10))
plt.plot(PeriodCount['index'], PeriodCount['count'], marker='o')
plt.title('Total Free Throws per quarter', fontsize = 18)
plt.xlabel('Period', fontsize = 18)
plt.ylabel('Free Throws', fontsize = 18)

Histogram of Free throws taken by season

The following histogram shows the number of free throws taken per season in the NBA (in years). We can see that most seasons range with 60,000 to 70,000 free throws. However, there was a decrease in 2011, with under 50,000 free throws.

plt.figure(figsize=(18,20))
plt.hist(x= df['season'])
## (array([67612., 65500., 65355., 64804., 64137., 48459., 58376., 62290.,
##        60131., 61355.]), array([0. , 0.9, 1.8, 2.7, 3.6, 4.5, 5.4, 6.3, 7.2, 8.1, 9. ]), <BarContainer object of 10 artists>)
plt.title('Free Throws Taken by Season', fontsize=18)
plt.xlabel('Season', fontsize=18)
plt.ylabel('Free throws', fontsize=18)
plt.show()

Pie Chart of free throws Lebron

This pie chart compares the regular time free throws verses overtime free throws taken by Lebron James. Out of all the players in the NBA, Lebron holds the record for the greatest number of free throws. We can see in this chart that 98.5% of these free throws take place during the regular time periods while only 1.5% take place in overtime. This disparity was also noted in the first line graph which showed the general population of NBA players also take the majority of their free throws in the regular time periods.

# DataFrame of Total Free throws by quarter 
# Create Count DataFrame

x = df.groupby(['player','period'])['player'].count().reset_index(name='count')

# Dataframe of total free throws
y = df.groupby(['player'])['period'].count().reset_index(name='count')
totalfts = pd.DataFrame(y)


# Sort Dataframe in descending order

totalfts = totalfts.sort_values(by='count', ascending=False)

# Player that has shot the  most free throws (Lebron James)

TopFTPlayer = totalfts.iloc[0,0]


df2 = pd.DataFrame(x)

# Non Overtime Dataframe
df3 = df2[df2['period'] < 5]
# Top Player Free Throw Dataframe
TopPlayer4 = df3[df3['player'] == TopFTPlayer]

TopPlayerAll = df2[df2['player'] == TopFTPlayer]

# Sum of Free throws taken
TotalLebronFT = TopPlayerAll['count'].sum() #1699

OvertimeFT =  TotalLebronFT - (TopPlayerAll[TopPlayerAll['period'] < 5])['count'].sum() #1680
#print(TotalLebronFT)
#print(OvertimeFT)


d = {'Play': ['Regular', 'Overtime'], 'count': [TotalLebronFT, OvertimeFT]}
RvOTFTLebron = pd.DataFrame(data=d)


plt.figure(figsize=(18,20))
plt.title('Pie Chart of Regular Time Free Throws v Overtime Free Throws', fontsize = 14)
plt.pie(RvOTFTLebron['count'], labels=['RT','OT'], autopct='%1.1f%%', textprops={'fontsize':20})
## ([<matplotlib.patches.Wedge object at 0x000001DF0B68BEE0>, <matplotlib.patches.Wedge object at 0x000001DF0B6C4160>], [Text(-1.0988343515073422, 0.050626751302435595, 'RT'), Text(1.0988343515073422, -0.05062675130243622, 'OT')], [Text(-0.5993641917312775, 0.027614591619510322, '98.5%'), Text(0.5993641917312775, -0.027614591619510662, '1.5%')])
plt.show()

Lebrons free throws per quarter (Regular Time)

This bar-graph specifically looks at when the greatest amount of Lebron’s free throws take place. We can see that period 4 is the quarter with the highest number of free throws (over 2,000). The rest of the players in the NBA also take the majority of their free throws in this quarter as well, as shown in the first line graph. We can see in this histogram that the other three periods have similar amounts of free throws, with period 1 being slightly lower than the others.

# Create Plot

# X and Y PLot
plt.bar(TopPlayer4['period'], TopPlayer4['count'])
## <BarContainer object of 4 artists>
plt.title('Lebron James Free Throws per quarter', fontsize=18)
plt.xlabel('Period', fontsize=18)
plt.ylabel('Free Throws', fontsize=18)
plt.xticks([1,2,3,4])
## ([<matplotlib.axis.XTick object at 0x000001DF0B6C6D10>, <matplotlib.axis.XTick object at 0x000001DF0B6C6CE0>, <matplotlib.axis.XTick object at 0x000001DF0B6C4D60>, <matplotlib.axis.XTick object at 0x000001DF0B6F3A00>], [Text(1, 0, '1'), Text(2, 0, '2'), Text(3, 0, '3'), Text(4, 0, '4')])
plt.show()

HeatMap

This heat map shows that during period 4 in the 2006-2007 NBA season Lebron amounted to 299 free throws which was more than any other period in any other season. The first period of the 2015-2016 consisted of the least number of free throws(87).


# DataFrame of Total Free throws by quarter 
# Create Count DataFrame
x = df.groupby(['player','period'])['player'].count().reset_index(name='count')

df2 = pd.DataFrame(x)

y = x = df.groupby(['player'])['period'].count().reset_index(name='count')
totalfts = pd.DataFrame(y)

# Sort Dataframe in descending order

totalfts = totalfts.sort_values(by='count', ascending=False)
TopFTPlayer = totalfts.iloc[0,0]
totalwithYear = df.groupby(['player','period','season'])['player'].count().reset_index(name='count')


# Get
LJYear = totalwithYear[totalwithYear['player']== TopFTPlayer]
LJYear = LJYear[LJYear['period'] <5]

hm_df = pd.pivot_table(LJYear, index='season', columns='period', values='count')



fig = plt.figure(figsize=(18,10))
ax = fig.add_subplot(1,1,1)



ax = sns.heatmap(hm_df, linewidth =0.2, annot = True, cmap ='coolwarm',fmt=',.0f')


plt.title('Heatmap of Free Throws Taken by season and quarter for Lebron James', fontsize=18)
plt.xlabel('Period', fontsize=18, labelpad=10)
plt.ylabel('Season', fontsize=18, labelpad=10)
ax.set_xticklabels(['1','2','3','4'])
plt.show()