def update_team_comparison(year, indicators, metric, hover_data, click_data): df1 = subset_years(df_eoy, year) dff = df1.melt(id_vars='team', value_vars=indicators, var_name='indicator') dff['indicator'] = pd.Categorical(dff.indicator, indicators) dff = pd.merge(dff, palette_df, how='outer') dff = dff.sort_values(['indicator', 'team'], ascending=[False, True]) dff["rank"] = dff.groupby("indicator")["value"].rank("min", ascending=False) if hover_data: i = hover_data['points'][0]['curveNumber'] elif click_data: i = click_data['points'][0]['curveNumber'] else: i = 0 marker_sizes = [10] * len(dff.team.unique()) line_widths = [0.4] * len(dff.team.unique()) marker_sizes[i] = 20 line_widths[i] = 2 metric2 = "value" if metric == "value": metric2 = "rank" return { 'data': [ go.Scatter( x=dff[dff.team == t][metric], y=dff[dff.team == t]['indicator'], name=t, text=round(dff[dff.team == t][metric2], 2), mode='markers+lines', marker={ 'size': marker_sizes[i], # 10 'color': dff[dff.team == t]['color1'], 'line': { 'width': 2, 'color': dff[dff.team == t]['color2'] } }, line={ 'width': line_widths[i], 'color': map_colors(t, palette, 1) }) for i, t in enumerate(dff.team.unique()) ], 'layout': go.Layout( # title=team, xaxis=dict(title=metric, titlefont=dict(size=18)), height=200 + 100 * len(indicators), margin={ 'l': 200, 'b': 40, 't': 40, 'r': 40 }, hovermode='closest') }
def update_matchup_heatmap(division, year, indicator): df1 = subset_years(df_t_wide, year) teams = division_dict[division] opponents = division_dict[division] df1 = df1.loc[(df1.team.isin(teams)) & (df1.opponent.isin(opponents))] df1 = df1.groupby(['team', 'opponent'])[indicator].mean().reset_index() df1 = df1.sort_values(['team', 'opponent'], ascending=[False, True]) # return { 'data': [ go.Heatmap(z=round(df1[indicator], 2), x=df1.opponent, y=df1.team, reversescale=True, text=[indicator] * len(df1), hoverinfo='z+text') ], 'layout': go.Layout(title=f'Average {indicator} by matchup', margin={ 'l': 200, 'b': 40, 't': 40, 'r': 40 }, yaxis=dict(title='Team'), xaxis=dict(title='Opponent')) }
def update_players(team, year, indicators, min_games, rate_type, hover_data, click_data): df1 = subset_years(df_p, year) df1 = df1[df1.team == team] df1 = apply_game_threshold(df1, n_games=min_games) dff = df1.groupby('player')[player_indicators].sum().reset_index() dff = aggregate_rates(dff, player_indicators, rate_type) dff = dff.melt(id_vars='player', value_vars=indicators, var_name='indicator') dff['indicator'] = pd.Categorical(dff.indicator, indicators) dff = dff.sort_values(['indicator', 'player'], ascending=[False, True]) players = dff.player.unique() if hover_data: i = hover_data['points'][0]['curveNumber'] elif click_data: i = click_data['points'][0]['curveNumber'] else: i = 0 opacities = [0.5] * len(players) marker_sizes = [10] * len(players) line_widths = [0.4] * len(players) opacities[i] = 1 marker_sizes[i] = 20 line_widths[i] = 2 return { 'data': [ go.Scatter( x=dff[dff.player == p]['value'], y=dff[dff.player == p]['indicator'], name=p, mode='markers+lines', marker={ 'size': marker_sizes[i], 'opacity': opacities[i], # 'line': {'width': 0} }, line={'width': line_widths[i]}) for i, p in enumerate(players) ], 'layout': go.Layout( # title=team, height=80 + 80 * len(indicators), margin={ 'l': 120, 'b': 40, 't': 40, 'r': 40 }, hovermode='closest') }
def make_conversion_plot(team, year, line): """TODO - refactor so easier to move to viz utils, for now it has too many dependencies""" df1 = subset_years(df_p, year) df1 = df1[df1.team == team] # Todo - add this to player indicators? df1['Proportion Offensive'] = df1[f'O Points Played'] / df1['Points Played'] title = "" if line == 'O': title = "Offense" elif line == 'D': title = "Defense" return { 'data': [ go.Scatter( x=df1[f'{line} Points Played'], y=df1[f'{line}-line Scoring Efficiency'], # name=p, mode='markers', marker=dict( color=df1['Proportion Offensive'], colorscale='RdBu', reversescale=True, showscale=True, colorbar=dict(title='% Offensive', ), ), text=df1['player'], # 'size': 10, # 'opacity': 0.5, # 'line': {'width': 0} # line={'width': 0.4} ) ], 'layout': go.Layout( # title=title, height=400, margin={ 'l': 120, 'b': 40, 't': 40, 'r': 40 }, hovermode='closest', yaxis=dict( range=[0, 1], title=f'{line}-line Scoring Efficiency', ), xaxis=dict(title=f'Points Played ({line})')) }
def update_leaderboard(indicator, year, rate_type, min_games): df1 = subset_years(df_p, year) df1 = apply_game_threshold(df1, n_games=min_games) dff = df1.groupby('player')[player_indicators].sum().reset_index() dff = aggregate_rates(dff, player_indicators, rate_type) dff = dff.melt(id_vars='player', value_vars=player_indicators, var_name='indicator') n_players = 20 dff = dff[dff.indicator == indicator] # Get correct team & color for specific year if year == 'All seasons': player_map = player_team[player_team['year'] == 2018] else: player_map = player_team[player_team['year'] == year] dff = pd.merge(player_map, dff) dff = pd.merge(dff, palette_df, how='outer').sort_values('value', ascending=False)[:n_players] dff = dff.sort_values('value', ascending=True) # plotly seems to invert the order? return { 'data': [ go.Scatter( x=dff['value'], y=dff['player'], text=dff['team'], mode='markers', marker={ 'size': 15, 'color': dff['color1'], 'line': { 'width': 3, 'color': dff['color2'] } }, ) ], 'layout': go.Layout( # title=indicator, height=600, margin={ 'l': 120, 'b': 40, 't': 40, 'r': 0 }, hovermode='closest') }
def update_team_timeseries(team, year, indicators): df1 = subset_years(df_t, year) df1 = df1[df1.team == team] dff = df1.sort_values(['indicator', 'date'], ascending=[False, True]) return { 'data': [ go.Scatter( x=dff[dff.indicator == i]['date'], y=dff[dff.indicator == i]['value'], name=i, text=dff['opponent'], mode='lines+markers', marker={ 'size': 15, # 'opacity': 0.5, 'color': dff['opponent_color1'], 'line': { 'width': 3, 'color': dff['opponent_color2'] } }, line={'width': 3}) for i in indicators ], 'layout': go.Layout( # title=team, height=400, margin={ 'l': 120, 'b': 40, 't': 40, 'r': 40 }, hovermode='closest') }