Esempio n. 1
0
def team_fline_shot_rates_scatter(team, min_line_toi=50, **kwargs):
    """
    Creates a scatterplot of team forward line shot attempr rates.

    :param team: int or str, team
    :param min_line_toi: int, number of minutes for pair to qualify
    :param kwargs: Use season- or date-range-related kwargs only.

    :return:
    """

    kwargs['team'] = team

    startdate, enddate = vhelper.get_startdate_enddate_from_kwargs(**kwargs)
    rates = get_fline_shot_rates(team, startdate, enddate)
    lines = drop_duplicate_lines(rates)
    xy = _add_xy_names_for_fline_graph(lines)

    xy = _get_colors_markers_for_fline_scatter(xy)

    # Remove players who didn't have at least one line combination above minimum
    # Remove total TOI rows first, then filter
    # Get indiv toi by finding index of max TOI of each group. Then anti-join lines onto indiv toi
    indivtoi = xy.ix[xy.groupby(['Name', 'PlayerID'], as_index=False)['TOI'].idxmax()] \
        [['Name', 'PlayerID', 'TOI', 'X', 'Y', 'Color', 'Marker']] \
        .sort_values('TOI', ascending=False)
    xy = helper.anti_join(xy.query('TOI >= {0:d}'.format(60 * min_line_toi)),
                          indivtoi[['Name', 'PlayerID', 'TOI']],
                          on=['Name', 'PlayerID', 'TOI'])

    # Now get sizes. Scaling is too poor if I do it earlier
    xy = _get_point_sizes_for_fline_scatter(xy)

    # Plot individuals
    # Ordinarily would filter for players with a qualifying line combo again
    # But this would eliminate some fourth liners who are lineup constants
    # Instead, make sure anybody with at least as much TOI as anybody on a qualifying line is in
    mintoi = indivtoi[['PlayerID', 'TOI']] \
        .merge(pd.DataFrame({'PlayerID': xy.PlayerID.unique()}), how='inner', on='PlayerID') \
        .TOI.min()
    indivtoi = indivtoi.query('TOI >= {0:d}'.format(int(mintoi)))

    fig = plt.figure(figsize=[8, 6])
    ax = plt.gca()
    for _, name, _, toi, x, y, color, marker in indivtoi.itertuples():
        # Size gets too crazy, so fix it
        ax.scatter([x], [y],
                   marker=marker,
                   s=200,
                   c=color,
                   label=helper.get_lastname(name))

    # Now plot lines
    for name in xy.Name.unique():
        temp = xy.query('Name == "{0:s}"'.format(name)).sort_values(
            'TOI', ascending=False)
        if len(temp) == 0:
            continue
        ax.scatter(temp.X.values,
                   temp.Y.values,
                   marker=temp.Marker.values[0],
                   s=temp.Size.values,
                   c=temp.Color.values)

    ax.set_xlabel('CF60')
    ax.set_ylabel('CA60')
    num_players = len(xy.Name.unique())
    plt.legend(loc='upper center', fontsize=6, ncol=num_players // 3 + 1)
    vhelper.add_good_bad_fast_slow()
    vhelper.add_cfpct_ref_lines_to_plot(ax)

    ax.set_title(', '.join(
        vhelper.generic_5v5_log_graph_title('F line shot rates', **kwargs)))

    return vhelper.savefilehelper(**kwargs)
Esempio n. 2
0
def parallel_usage_chart(**kwargs):
    """

    :param kwargs: Defaults to take last month of games for all teams.

    :return: nothing, or figure
    """
    if 'startdate' not in kwargs and 'enddate' not in kwargs and \
                    'startseason' not in kwargs and 'endseason' not in kwargs:
        kwargs['last_n_days'] = 30

    qocqot = vhelper.get_and_filter_5v5_log(**kwargs)
    qocqot = qocqot[['PlayerID', 'TOION', 'TOIOFF',
                     'FCompSum', 'FCompN', 'DCompSum', 'DCompN',
                     'FTeamSum', 'FTeamN', 'DTeamSum', 'DTeamN']] \
        .groupby('PlayerID').sum().reset_index()
    qocqot.loc[:, 'FQoC'] = qocqot.FCompSum / qocqot.FCompN
    qocqot.loc[:, 'FQoT'] = qocqot.FTeamSum / qocqot.FTeamN
    qocqot.loc[:, 'DQoC'] = qocqot.DCompSum / qocqot.DCompN
    qocqot.loc[:, 'DQoT'] = qocqot.DTeamSum / qocqot.DTeamN
    qocqot.loc[:, 'TOI60'] = qocqot.TOION / (qocqot.TOION + qocqot.TOIOFF)
    qocqot = qocqot.dropna().sort_values('TOI60', ascending=False)  # In case I have zeroes

    qocqot.loc[:, 'PlayerName'] = qocqot.PlayerID.apply(lambda x: helpers.get_lastname(players.player_as_str(x)))
    qocqot.loc[:, 'PlayerInitials'] = qocqot.PlayerID.apply(lambda x: helpers.get_lastname(players.player_as_str(x)))
    qocqot.loc[:, 'Position'] = qocqot.PlayerID.apply(lambda x: players.get_player_position(x))
    qocqot.drop({'FCompSum', 'FCompN', 'DCompSum', 'DCompN', 'FTeamSum', 'FTeamN', 'DTeamSum', 'DTeamN',
                 'PlayerID'}, axis=1, inplace=True)

    # Reorder columns for the parallel coordinates plot
    qocqot = qocqot[['FQoT', 'FQoC', 'DQoC', 'DQoT', 'TOION', 'TOIOFF', 'TOI60', 'PlayerName', 'PlayerInitials',
                     'Position']] \
        .sort_values('TOION', ascending=False) \
        .drop({'TOION', 'TOION', 'TOIOFF', 'TOI60'}, axis=1)

    fig, axes = plt.subplots(2, 2, sharex=True, sharey=True, figsize=[11, 7])

    forwards = qocqot.query('Position != "D"')
    centers = forwards.query('Position == "C"').drop('Position', axis=1).iloc[:6, :]
    wingers = forwards.query('Position != "C"').drop('Position', axis=1).iloc[:6, :]
    forwards.drop('Position', axis=1, inplace=True)
    vhelper.parallel_coords(forwards, centers, 'PlayerInitials', 'PlayerName', axes.flatten()[0])
    vhelper.parallel_coords(forwards, wingers, 'PlayerInitials', 'PlayerName', axes.flatten()[1])

    alldefense = qocqot.query('Position == "D"').drop('Position', axis=1)
    defense = alldefense.iloc[:6, :]
    vhelper.parallel_coords(alldefense, defense, 'PlayerInitials', 'PlayerName', axes.flatten()[2])

    other_players = pd.concat([qocqot.drop('Position', axis=1), centers, wingers, defense]) \
        .drop_duplicates(keep=False).iloc[:6, :]
    vhelper.parallel_coords(pd.concat([forwards, defense]), other_players, 'PlayerInitials', 'PlayerName', axes.flatten()[3])

    fig.text(0.5, 0.04, 'Statistic (based on TOI/60)', ha='center')
    fig.text(0.04, 0.5, 'Minutes', va='center', rotation='vertical')
    axes.flatten()[0].set_title('Top centers')
    axes.flatten()[1].set_title('Top wingers')
    axes.flatten()[2].set_title('Top defense')
    axes.flatten()[3].set_title('Others')

    fig.suptitle(_parallel_usage_chart_title(**kwargs))

    return vhelper.savefilehelper(**kwargs)