Example #1
0
def shooting_plot(path,
                  shot_df,
                  player_id,
                  season_id,
                  player_title,
                  player_name,
                  isCareer=False,
                  min_year=0,
                  max_year=0,
                  plot_size=(12, 12),
                  gridNum=30):

    # get the shooting percentage and number of shots for all bins, all shots, and a subset of some shots
    (
        ShootingPctLocs, shotNumber
    ), shot_pts_all, shot_pts_3, shot_pts_2, shot_pts_mid, shot_pts_NONres, shot_pts_res, shot_count_all, shot_count_3, shot_count_2, shot_count_mid, shot_count_NONres, shot_count_res, team_list = find_shootingPcts(
        shot_df, gridNum)

    # returns the effective FG% values for usage later in the chart's text
    def get_efg(shot_pts, shot_count):
        try:
            eff_fg_float = float(
                (float(shot_pts) / 2.0) / float(shot_count)) * 100.0
        except ZeroDivisionError:
            eff_fg_float = 0.0
        eff_fg = ("%.2f" % eff_fg_float)
        pct_float = float(shot_count) / float(shot_count_all) * 100
        pct = ("%.2f" % pct_float)

        return eff_fg_float, eff_fg, pct_float, pct

    eff_fg_all_float, eff_fg_all, pct_all_float, pct_all = get_efg(
        shot_pts_all, shot_count_all)
    eff_fg_3_float, eff_fg_3, pct_3_float, pct_3 = get_efg(
        shot_pts_3, shot_count_3)
    eff_fg_2_float, eff_fg_2, pct_2_float, pct_2 = get_efg(
        shot_pts_2, shot_count_2)
    eff_fg_mid_float, eff_fg_mid, pct_mid_float, pct_mid = get_efg(
        shot_pts_mid, shot_count_mid)
    eff_fg_NONres_float, eff_fg_NONres, pct_NONres_float, pct_NONres = get_efg(
        shot_pts_NONres, shot_count_NONres)
    eff_fg_res_float, eff_fg_res, pct_res_float, pct_res = get_efg(
        shot_pts_res, shot_count_res)

    # Creates a text string for all teams that a player has played on in a given season or career
    team_text = ""
    if len(team_list) == 1:
        team_text = str(team_list[0])
    else:
        i = 0
        for team in team_list[0:-1]:
            if i % 2 == 0 and i > 0:
                team_text += '\n'
            text_add = '%s, ' % str(team)
            team_text += text_add
            i += 1
        if i % 2 == 0:
            team_text += '\n'
        team_text += str(team_list[-1])

    # set the figure for drawing on
    fig = plt.figure(figsize=(12, 12))

    # cmap will be used as our color map going forward
    cmap = mymap

    # where to place the plot within the figure, first two attributes are the x_min and y_min, and the next 2 are the % of the figure that is covered in the x_direction and y_direction (so in this case, our plot will go from (0.05, 0.15) at the bottom left, and stretches to (0.85,0.925) at the top right)
    ax = plt.axes([0.05, 0.15, 0.81, 0.775])

    # setting the background color using a hex code (http://www.rapidtables.com/web/color/RGB_Color.htm)
    ax.set_axis_bgcolor('#08374B')

    # draw the outline of the court
    draw_court(outer_lines=False)

    # specify the dimensions of the court we draw
    plt.xlim(-250, 250)
    plt.ylim(370, -30)

    # draw player image
    zoom = 1  # we don't need to zoom the image at all
    img = acquire_playerPic(player_id, zoom)
    ax.add_artist(img)

    # specify the % a zone that we want to correspond to a maximum sized hexagon [I have this set to any zone with >= 1% of all shots will have a maximum radius, but it's free to be changed based on personal preferences]
    max_radius_perc = 1.0
    max_rad_multiplier = 100.0 / max_radius_perc

    # changing to what power we want to scale the area of the hexagons as we increase/decrease the radius. This value can also be changed for personal preferences.
    area_multiplier = (3. / 4.)

    # draw hexagons
    # i is the bin#, and shots is the shooting% for that bin
    for i, shots in enumerate(ShootingPctLocs):
        x, y = shotNumber.get_offsets()[i]

        # we check the distance from the hoop the bin is. If it in 3pt territory, we add a multiplier of 1.5 to the shooting% to properly encapsulate eFG%
        dist = math.sqrt(x**2 + y**2)
        mult = 1.0
        if abs(x) >= 220:
            mult = 1.5
        elif dist / 10 >= 23.75:
            mult = 1.5
        else:
            mult = 1.0

        # Setting the eFG% for a bin, making sure it's never over 1 (our maximum color value)
        bin_pct = min(shots * mult, 1.0)
        hexes = RegularPolygon(
            shotNumber.get_offsets()[i],  #x/y coords
            numVertices=6,
            radius=(295 / gridNum) *
            ((max_rad_multiplier * ((shotNumber.get_array()[i])) /
              shot_count_all)**(area_multiplier)),
            color=cmap(bin_pct),
            alpha=0.95,
            fill=True)

        # setting a maximum radius for our bins at 295 (personal preference)
        if hexes.radius > 295 / gridNum:
            hexes.radius = 295 / gridNum
        ax.add_patch(hexes)

    # creating the frequency legend
    # we want to have 4 ticks in this legend so we iterate through 4 items
    for i in range(0, 4):
        base_rad = max_radius_perc / 4

        # the x,y coords for our patch (the first coordinate is (-205,415), and then we move up and left for each addition coordinate)
        patch_x = -205 - (10 * i)
        patch_y = 365 - (14 * i)

        # specifying the size of our hexagon in the frequency legend
        patch_rad = (299.9 / gridNum) * ((base_rad +
                                          (base_rad * i))**(area_multiplier))
        patch_perc = base_rad + (i * base_rad)

        # the x,y coords for our text
        text_x = patch_x + patch_rad + 2
        text_y = patch_y

        patch_axes = (patch_x, patch_y)

        # the text will be slightly different for our maximum sized hexagon,
        if i < 3:
            text_text = ' %s%% of Attempted Shots' % ('%.2f' % patch_perc)
        else:
            text_text = '$\geq$%s%% of Attempted Shots' % (str(patch_perc))

        # draw the hexagon. the color=map(eff_fg_all_float/100) makes the hexagons in the legend the same color as the player's overall eFG%
        patch = RegularPolygon(patch_axes,
                               numVertices=6,
                               radius=patch_rad,
                               color=cmap(eff_fg_all_float / 100),
                               alpha=0.95,
                               fill=True)
        ax.add_patch(patch)

        # add the text for the hexagon
        ax.text(text_x,
                text_y,
                text_text,
                fontsize=12,
                horizontalalignment='left',
                verticalalignment='center',
                family='DejaVu Sans',
                color='white',
                fontweight='bold')

    # Add a title to our frequency legend (the x/y coords are hardcoded).
    # Again, the color=map(eff_fg_all_float/100) makes the hexagons in the legend the same color as the player's overall eFG%
    ax.text(-235,
            310,
            'Zone Frequencies',
            fontsize=15,
            horizontalalignment='left',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color=cmap(eff_fg_all_float / 100),
            fontweight='bold')

    # Add a title to our chart (just the player's name)

    chart_title = "%s" % (player_title.upper())
    ax.text(31.25,
            -40,
            chart_title,
            fontsize=29,
            horizontalalignment='center',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color=cmap(eff_fg_all_float / 100),
            fontweight='bold')

    # Add user text
    ax.text(-250,
            -31,
            'CHARTS BY @NBAChartBot',
            fontsize=10,
            horizontalalignment='left',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # Add data source text
    ax.text(31.25,
            -31,
            'DATA FROM STATS.NBA.COM',
            fontsize=10,
            horizontalalignment='center',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # Add date text
    _date = date.today()

    ax.text(250,
            -31,
            'AS OF %s' % (str(_date)),
            fontsize=10,
            horizontalalignment='right',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # adding breakdown of eFG% by shot zone at the bottom of the chart
    ax.text(300,
            380,
            '%s Points - %s Shots [TOTAL (%s%% of total)] (%s eFG%%)'
            '\n%s Points - %s Shots [All 3PT (%s%%)] (%s eFG%%)'
            '\n%s Points - %s Shots [All 2PT (%s%%)] (%s eFG%%)'
            '\n%s Points - %s Shots [Mid-Range (%s%%)] (%s eFG%%)'
            '\n%s Points - %s Shots [Paint (Non-Restricted) (%s%%)] (%s eFG%%)'
            '\n%s Points - %s Shots [Paint (Restricted) (%s%%)] (%s eFG%%)' %
            (shot_pts_all, shot_count_all, pct_all, eff_fg_all, shot_pts_3,
             shot_count_3, pct_3, eff_fg_3, shot_pts_2, shot_count_2, pct_2,
             eff_fg_2, shot_pts_mid, shot_count_mid, pct_mid, eff_fg_mid,
             shot_pts_NONres, shot_count_NONres, pct_NONres, eff_fg_NONres,
             shot_pts_res, shot_count_res, pct_res, eff_fg_res),
            fontsize=12,
            horizontalalignment='right',
            verticalalignment='top',
            family='DejaVu Sans',
            color='white',
            linespacing=1.5)

    # adding which season the chart is for, as well as what teams the player is on
    if len(team_list) > 10:
        ax.text(-250,
                380,
                '%s Regular Season'
                '\n%s' % (season_id, team_text),
                fontsize=10,
                horizontalalignment='left',
                verticalalignment='top',
                family='DejaVu Sans',
                color='white',
                linespacing=1.3)
    else:
        ax.text(-250,
                380,
                '%s Regular Season'
                '\n%s' % (season_id, team_text),
                fontsize=12,
                horizontalalignment='left',
                verticalalignment='top',
                family='DejaVu Sans',
                color='white',
                linespacing=1.5)

    # adding a color bar for reference
    ax2 = fig.add_axes([0.875, 0.15, 0.04, 0.775])
    cb = mpb.colorbar.ColorbarBase(ax2, cmap=cmap, orientation='vertical')
    cbytick_obj = plt.getp(cb.ax.axes, 'yticklabels')
    plt.setp(cbytick_obj, color='white', fontweight='bold')
    cb.set_label('Effective Field Goal %',
                 family='DejaVu Sans',
                 color='white',
                 fontweight='bold',
                 labelpad=-9,
                 fontsize=14)
    cb.set_ticks([0.0, 0.25, 0.5, 0.75, 1.0])
    cb.set_ticklabels(['0%', '25%', '50%', '75%', '$\mathbf{\geq}$100%'])

    # if the isCareer argument is set to True, we have to slightly alter the title of the plot
    title_efg = eff_fg_all_float

    if isCareer is False:
        figtit = path + 'shot_charts_%s_%s_%s.png' % (
            player_name, season_id, str(int(round(eff_fg_all_float))))
    else:
        figtit = path + 'shot_charts_%s_CAREER_%s-%s_%s.png' % (
            player_name, min_year, max_year, str(int(round(eff_fg_all_float))))
    plt.savefig(figtit, facecolor='#305E72', edgecolor='black')
    plt.clf()
def shooting_plot(dataType,
                  path,
                  shot_df,
                  _id,
                  season_id,
                  _title,
                  _name,
                  isCareer=False,
                  min_year=0,
                  max_year=0,
                  plot_size=(24, 24),
                  gridNum=30):

    # get the shooting percentage and number of shots for all bins, all shots, and a subset of some shots
    (ShootingPctLocs,
     shotNumber), shot_count_all = find_shootingPcts(shot_df, gridNum)

    all_efg_percentile = float(
        helper_data.get_metrics(dataType, _id, season_id, isCareer, 'all',
                                'EFG_Percentile'))

    color_efg = max(min((all_efg_percentile / 100), 1.0), 0.0)

    paa = float(
        helper_data.get_metrics(dataType, _id, season_id, isCareer, 'all',
                                'paa'))

    # set the figure for drawing on
    fig = plt.figure(figsize=(24, 24))

    # cmap will be used as our color map going forward
    cmap = mymap

    # where to place the plot within the figure, first two attributes are the x_min and y_min, and the next 2 are the % of the figure that is covered in the x_direction and y_direction (so in this case, our plot will go from (0.05, 0.15) at the bottom left, and stretches to (0.85,0.925) at the top right)
    ax = plt.axes([0.05, 0.15, 0.81, 0.775])

    # setting the background color using a hex code (http://www.rapidtables.com/web/color/RGB_Color.htm)
    # ax.set_facecolor('#0C232E')
    ax.set_facecolor('#152535')

    # draw the outline of the court
    draw_court(outer_lines=False)

    # specify the dimensions of the court we draw
    plt.xlim(-250, 250)
    plt.ylim(370, -30)

    # drawing the bottom right image
    zoom = 1  # we don't need to zoom the image at all
    if dataType == 'player':
        img = acquire_playerPic(_id, zoom)
    else:
        img = acquire_teamPic(season_id, _title, _id, zoom)
    ax.add_artist(img)

    # specify the % a zone that we want to correspond to a maximum sized hexagon [I have this set to any zone with >= 1% of all shots will have a maximum radius, but it's free to be changed based on personal preferences]
    max_radius_perc = 1.0
    max_rad_multiplier = 100.0 / max_radius_perc

    # changing to what power we want to scale the area of the hexagons as we increase/decrease the radius. This value can also be changed for personal preferences.
    area_multiplier = (3. / 4.)

    lg_efg = float(helper_data.get_lg_efg(season_id, isCareer))

    # draw hexagons
    # i is the bin#, and shots is the shooting% for that bin
    for i, shots in enumerate(ShootingPctLocs):
        x, y = shotNumber.get_offsets()[i]

        # we check the distance from the hoop the bin is. If it in 3pt territory, we add a multiplier of 1.5 to the shooting% to properly encapsulate eFG%
        dist = math.sqrt(x**2 + y**2)
        mult = 1.0
        if abs(x) >= 220:
            mult = 1.5
        elif dist / 10 >= 23.75:
            mult = 1.5
        else:
            mult = 1.0

        # Setting the eFG% for a bin, making sure it's never over 1 (our maximum color value)
        color_pct = ((shots * mult) / lg_efg) - 0.5
        bin_pct = max(min(color_pct, 1.0), 0.0)
        hexes = RegularPolygon(
            shotNumber.get_offsets()[i],  #x/y coords
            numVertices=6,
            radius=(295 / gridNum) *
            ((max_rad_multiplier * ((shotNumber.get_array()[i])) /
              shot_count_all)**(area_multiplier)),
            color=cmap(bin_pct),
            alpha=0.95,
            fill=True)

        # setting a maximum radius for our bins at 295 (personal preference)
        if hexes.radius > 295 / gridNum:
            hexes.radius = 295 / gridNum
        ax.add_patch(hexes)

    # creating the frequency legend
    # we want to have 4 ticks in this legend so we iterate through 4 items
    for i in range(0, 4):
        base_rad = max_radius_perc / 4

        # the x,y coords for our patch (the first coordinate is (-205,415), and then we move up and left for each addition coordinate)
        patch_x = -205 - (10 * i)
        patch_y = 365 - (14 * i)

        # specifying the size of our hexagon in the frequency legend
        patch_rad = (299.9 / gridNum) * ((base_rad +
                                          (base_rad * i))**(area_multiplier))
        patch_perc = base_rad + (i * base_rad)

        # the x,y coords for our text
        text_x = patch_x + patch_rad + 2
        text_y = patch_y

        patch_axes = (patch_x, patch_y)

        # the text will be slightly different for our maximum sized hexagon,
        if i < 3:
            text_text = ' %s%% of Attempted Shots' % ('%.2f' % patch_perc)
        else:
            text_text = '$\geq$%s%% of Attempted Shots' % (str(patch_perc))

        # draw the hexagon. the color=map(eff_fg_all_float/100) makes the hexagons in the legend the same color as the player's overall eFG%
        patch = RegularPolygon(patch_axes,
                               numVertices=6,
                               radius=patch_rad,
                               color=cmap(color_efg),
                               alpha=0.95,
                               fill=True)
        ax.add_patch(patch)

        # add the text for the hexagon
        ax.text(text_x,
                text_y,
                text_text,
                fontsize=16,
                horizontalalignment='left',
                verticalalignment='center',
                family='DejaVu Sans',
                color='white',
                fontweight='bold')

    # Add a title to our frequency legend (the x/y coords are hardcoded).
    # Again, the color=map(eff_fg_all_float/100) makes the hexagons in the legend the same color as the player's overall eFG%
    ax.text(-235,
            310,
            'Zone Frequencies',
            fontsize=16,
            horizontalalignment='left',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color=cmap(color_efg),
            fontweight='bold')

    # Add a title to our chart (just the player's name)
    chart_title = "%s | %s" % (_title.upper(), season_id)
    ax.text(31.25,
            -40,
            chart_title,
            fontsize=32,
            horizontalalignment='center',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color=cmap(color_efg),
            fontweight='bold')

    # Add user text
    ax.text(-250,
            -31,
            'CHARTS BY CONNOR REED (@NBAChartBot)',
            fontsize=16,
            horizontalalignment='left',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # Add data source text
    ax.text(31.25,
            -31,
            'DATA FROM STATS.NBA.COM',
            fontsize=16,
            horizontalalignment='center',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # Add date text
    _date = date.today()

    ax.text(250,
            -31,
            'AS OF %s' % (str(_date)),
            fontsize=16,
            horizontalalignment='right',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    key_text = get_key_text(dataType, _id, season_id, isCareer)
    # adding breakdown of eFG% by shot zone at the bottom of the chart
    ax.text(307,
            380,
            key_text,
            fontsize=20,
            horizontalalignment='right',
            verticalalignment='top',
            family='DejaVu Sans',
            color='white',
            linespacing=1.5)

    if dataType == 'player':
        teams_text, team_len = get_teams_text(_id, season_id, isCareer)
    else:
        teams_text = _title
        team_len = 0

    # adding which season the chart is for, as well as what teams the player is on
    if team_len > 12:
        ax.text(-250,
                380,
                season_id + ' Regular Season:\n' + teams_text,
                fontsize=20,
                horizontalalignment='left',
                verticalalignment='top',
                family='DejaVu Sans',
                color='white',
                linespacing=1.4)
    else:
        ax.text(-250,
                380,
                season_id + ' Regular Season:\n' + teams_text,
                fontsize=20,
                horizontalalignment='left',
                verticalalignment='top',
                family='DejaVu Sans',
                color='white',
                linespacing=1.6)

    # adding a color bar for reference
    ax2 = fig.add_axes([0.875, 0.15, 0.04, 0.775])
    cb = mpb.colorbar.ColorbarBase(ax2, cmap=cmap, orientation='vertical')
    cbytick_obj = plt.getp(cb.ax.axes, 'yticklabels')
    plt.setp(cbytick_obj, color='white', fontweight='bold', fontsize=16)
    cb.set_label('EFG+ (100 is League Average)',
                 family='DejaVu Sans',
                 color='white',
                 fontweight='bold',
                 labelpad=-4,
                 fontsize=24)
    cb.set_ticks([0.0, 0.25, 0.5, 0.75, 1.0])
    cb.set_ticklabels(
        ['$\mathbf{\leq}$50', '75', '100', '125', '$\mathbf{\geq}$150'])

    figtit = path + '%s(%s)_%s.png' % (_name, _id, season_id.replace(' ', ''))
    plt.savefig(figtit, facecolor='#2E3748', edgecolor='black')
    plt.clf()
def shooting_plot(path,
                  _type,
                  shot_df,
                  ids,
                  _names,
                  season_type,
                  start_date,
                  end_date,
                  custom_title,
                  custom_text,
                  custom_img,
                  start2,
                  end2,
                  plot_size=(12, 12),
                  gridNum=30):

    print '\t\tgetting shooting percentages in each zone.....'
    (ShootingPctLocs,
     shotNumber), shot_count_all = find_shootingPcts(shot_df, gridNum)
    print '\t\t\tDONE'

    print '\t\tcalculating metrics.....'
    metrics = calculate_metrics(_type, ids, start_date, end_date, season_type)
    print '\t\t\tDONE'

    all_efg_plus = float(get_metrics(metrics, 'all', 'efg_plus'))
    paa = float(get_metrics(metrics, 'all', 'paa'))
    color_efg = max(min(((all_efg_plus / 100) - 0.5), 1.0), 0.0)

    fig = plt.figure(figsize=(12, 12))

    cmap = mymap

    ax = plt.axes([0.05, 0.15, 0.81, 0.775])

    ax.set_axis_bgcolor('#0C232E')

    draw_court(outer_lines=False)

    plt.xlim(-250, 250)
    plt.ylim(370, -30)

    print '\t\tgetting icon.....'
    img = acquire_custom_pic(custom_img)
    ax.add_artist(img)
    print '\t\t\tDONE'

    max_radius_perc = 1.0
    max_rad_multiplier = 100.0 / max_radius_perc

    area_multiplier = (3. / 4.)

    lg_efg = float(
        get_lg_metrics(start_date, end_date, season_type, 'all', 'efg'))

    print '\t\tplotting each hex bin.....'
    # i is the bin#, and shots is the shooting% for that bin
    for i, shots in enumerate(ShootingPctLocs):
        x, y = shotNumber.get_offsets()[i]

        # we check the distance from the hoop the bin is. If it in 3pt territory, we add a multiplier of 1.5 to the shooting% to properly encapsulate eFG%
        dist = math.sqrt(x**2 + y**2)
        mult = 1.0
        if abs(x) >= 220:
            mult = 1.5
        elif dist / 10 >= 23.75:
            mult = 1.5
        else:
            mult = 1.0

        # Setting the eFG% for a bin, making sure it's never over 1 (our maximum color value)
        color_pct = ((shots * mult) / lg_efg) - 0.5
        bin_pct = max(min(color_pct, 1.0), 0.0)
        hexes = RegularPolygon(
            shotNumber.get_offsets()[i],  #x/y coords
            numVertices=6,
            radius=(295 / gridNum) *
            ((max_rad_multiplier * ((shotNumber.get_array()[i])) /
              shot_count_all)**(area_multiplier)),
            color=cmap(bin_pct),
            alpha=0.95,
            fill=True)

        # setting a maximum radius for our bins at 295 (personal preference)
        if hexes.radius > 295 / gridNum:
            hexes.radius = 295 / gridNum
        ax.add_patch(hexes)
    print '\t\t\tDONE'

    print '\t\tcreating the frequency legend.....'
    # we want to have 4 ticks in this legend so we iterate through 4 items
    for i in range(0, 4):
        base_rad = max_radius_perc / 4

        # the x,y coords for our patch (the first coordinate is (-205,415), and then we move up and left for each addition coordinate)
        patch_x = -205 - (10 * i)
        patch_y = 365 - (14 * i)

        # specifying the size of our hexagon in the frequency legend
        patch_rad = (299.9 / gridNum) * ((base_rad +
                                          (base_rad * i))**(area_multiplier))
        patch_perc = base_rad + (i * base_rad)

        # the x,y coords for our text
        text_x = patch_x + patch_rad + 2
        text_y = patch_y

        patch_axes = (patch_x, patch_y)

        # the text will be slightly different for our maximum sized hexagon,
        if i < 3:
            text_text = ' %s%% of Attempted Shots' % ('%.2f' % patch_perc)
        else:
            text_text = '$\geq$%s%% of Attempted Shots' % (str(patch_perc))

        # draw the hexagon. the color=map(eff_fg_all_float/100) makes the hexagons in the legend the same color as the player's overall eFG%
        patch = RegularPolygon(patch_axes,
                               numVertices=6,
                               radius=patch_rad,
                               color=cmap(color_efg),
                               alpha=0.95,
                               fill=True)
        ax.add_patch(patch)

        # add the text for the hexagon
        ax.text(text_x,
                text_y,
                text_text,
                fontsize=12,
                horizontalalignment='left',
                verticalalignment='center',
                family='DejaVu Sans',
                color='white',
                fontweight='bold')
    print '\t\t\tDONE'

    # Add a title to our frequency legend (the x/y coords are hardcoded).
    # Again, the color=map(eff_fg_all_float/100) makes the hexagons in the legend the same color as the player's overall eFG%
    ax.text(-235,
            310,
            'Zone Frequencies',
            fontsize=15,
            horizontalalignment='left',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color=cmap(color_efg),
            fontweight='bold')

    print '\t\tadding text.....'
    # Add a title to our chart (just the player's name)
    chart_title = "%s" % (custom_title)
    ax.text(31.25,
            -40,
            chart_title,
            fontsize=29,
            horizontalalignment='center',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color=cmap(color_efg),
            fontweight='bold')

    # Add user text
    ax.text(-250,
            -31,
            'CHARTS BY @NBAChartBot',
            fontsize=10,
            horizontalalignment='left',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # Add data source text
    ax.text(31.25,
            -31,
            'DATA FROM STATS.NBA.COM',
            fontsize=10,
            horizontalalignment='center',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    # Add date text
    _date = date.today()

    ax.text(250,
            -31,
            'AS OF %s' % (str(_date)),
            fontsize=10,
            horizontalalignment='right',
            verticalalignment='bottom',
            family='DejaVu Sans',
            color='white',
            fontweight='bold')

    key_text = get_key_text(_type, ids, start_date, end_date, metrics)
    # adding breakdown of eFG% by shot zone at the bottom of the chart
    ax.text(307,
            380,
            key_text,
            fontsize=12,
            horizontalalignment='right',
            verticalalignment='top',
            family='DejaVu Sans',
            color='white',
            linespacing=1.5)

    if _type == 'Player':
        teams_text, team_len = get_teams_text(ids, start_date, end_date,
                                              custom_text, season_type)
    elif _type == 'Team':
        team_len = len(_names)
        if custom_text is None:
            teams_text = ''
            if len(_names) == 1:
                teams_text = str(_names[0])
            else:
                i = 0
                for team in _names[0:-1]:
                    if i % 2 == 0 and i > 0:
                        teams_text += '\n'
                    text_add = '%s, ' % str(team)
                    teams_text += text_add
                    i += 1
                if i % 2 == 0:
                    teams_text += '\n'
                teams_text += str(_names[-1])
        else:
            teams_text = custom_text

    if custom_text is None:
        if season_type == 'Reg':
            season_type_text = 'Regular Season Shots:\n'
        elif season_type == 'AS':
            season_type_text = 'All Star Shots:\n'
        elif season_type == 'Pre':
            season_type_text = 'Pre Season Shots:\n'
        elif season_type == 'Post':
            season_type_text = 'Post Season Shots:\n'
        else:
            season_type_text = 'All Shots:\n'
    else:
        season_type_text = ''

    if team_len > 6:
        ax.text(-250,
                380,
                str(start2) + ' to ' + str(end2) + '\n' + season_type_text +
                teams_text,
                fontsize=8,
                horizontalalignment='left',
                verticalalignment='top',
                family='DejaVu Sans',
                color='white',
                linespacing=1.4)
    else:
        ax.text(-250,
                380,
                str(start2) + ' to ' + str(end2) + '\n' + season_type_text +
                teams_text,
                fontsize=11,
                horizontalalignment='left',
                verticalalignment='top',
                family='DejaVu Sans',
                color='white',
                linespacing=1.5)
    print '\t\t\tDONE'

    # adding a color bar for reference
    ax2 = fig.add_axes([0.875, 0.15, 0.04, 0.775])
    cb = mpb.colorbar.ColorbarBase(ax2, cmap=cmap, orientation='vertical')
    cbytick_obj = plt.getp(cb.ax.axes, 'yticklabels')
    plt.setp(cbytick_obj, color='white', fontweight='bold')
    cb.set_label('EFG+ (100 is League Average)',
                 family='DejaVu Sans',
                 color='white',
                 fontweight='bold',
                 labelpad=-4,
                 fontsize=14)
    cb.set_ticks([0.0, 0.25, 0.5, 0.75, 1.0])
    cb.set_ticklabels(
        ['$\mathbf{\leq}$50', '75', '100', '125', '$\mathbf{\geq}$150'])

    print 'ALL DONE\n\n'
    figtit = path
    plt.savefig(figtit, facecolor='#26373F', edgecolor='black')
    plt.clf()