line_color='#c7d5cc', pitch_color='#22312b') bins = (6, 4) ############################################################################## # Plotting using a single color and length fig, ax = pitch.draw(figsize=(16, 11), constrained_layout=True, tight_layout=False) fig.set_facecolor('#22312b') # plot the heatmap - darker colors = more passes originating from that square bs_heatmap = pitch.bin_statistic(df_pass.x, df_pass.y, statistic='count', bins=bins) hm = pitch.heatmap(bs_heatmap, ax=ax, cmap='Blues') # plot the pass flow map with a single color ('black') and length of the arrow (5) fm = pitch.flow(df_pass.x, df_pass.y, df_pass.end_x, df_pass.end_y, color='black', arrow_type='same', arrow_length=5, bins=bins, ax=ax) ax.set_title(f'{team1} pass flow map vs {team2}', fontsize=30, pad=-20) ############################################################################## # Plotting using a cmap and scaled arrows
nrows=4, tight_layout=False, constrained_layout=True) axes = axes.ravel() teams = df['Squad'].values vmin = df[pressure_cols].min().min( ) # we normalise the heatmaps with the min / max values vmax = df[pressure_cols].max().max() for i, ax in enumerate(axes[:len(teams)]): ax.set_title(teams[i], fontsize=20) # fill in the bin statistics from df and plot the heatmap bin_statistic['statistic'] = df.loc[df.Squad == teams[i], pressure_cols].values heatmap = pitch.heatmap(bin_statistic, ax=ax, cmap='coolwarm', vmin=vmin, vmax=vmax) # format and plot labels bin_statistic['statistic'] = (pd.DataFrame( bin_statistic['statistic']).round(0).astype( np.int32).applymap(lambda x: '{:d}%'.format(x)).values) annotate = pitch.label_heatmap(bin_statistic, color='white', fontsize=20, ax=ax, ha='center', va='center') # set a black path effect around the labels for label in annotate: label.set_path_effects([
# plot without endnote/ title axes title_height=0, endnote_height=0) bs1 = pitch.bin_statistic(df_team1.x, df_team1.y, bins=(18, 12)) bs2 = pitch.bin_statistic(df_team2.x, df_team2.y, bins=(18, 12)) # get the min/ max values for normalizing across both teams vmax = max(bs2['statistic'].max(), bs1['statistic'].max()) vmin = max(bs2['statistic'].min(), bs1['statistic'].min()) # set values where zero shots to nan values so it does not show up in the heatmap # i.e. zero values take the background color bs1['statistic'][bs1['statistic'] == 0] = np.nan bs2['statistic'][bs2['statistic'] == 0] = np.nan # set the vmin/ vmax so the colors depend on the minimum/maximum value for both teams hm1 = pitch.heatmap(bs1, ax=axes[0], cmap='Reds', vmin=vmin, vmax=vmax, edgecolor='#f9f9f9') hm2 = pitch.heatmap(bs2, ax=axes[0], cmap='Blues', vmin=vmin, vmax=vmax, edgecolor='#f9f9f9') # histograms with kdeplot team1_hist_y = sns.histplot(y=df_team1.y, ax=axes[1], color=red, linewidth=1, kde=True) team1_hist_x = sns.histplot(x=df_team1.x,
'related_event_df': False, 'shot_freeze_frame_df': False, 'tactics_lineup_df': False, 'warn': False } df = pd.concat([ read_event(f'{EVENT_SLUG}/{file}', **kwargs)['event'] for file in match_files ]) # filter chelsea pressure events mask_chelsea_pressure = (df.team_name == 'Chelsea FCW') & (df.type_name == 'Pressure') df = df.loc[mask_chelsea_pressure, ['x', 'y']] ############################################################################## # Plot the heatmaps # setup pitch pitch = Pitch(pitch_type='statsbomb', line_zorder=2, line_color='white') # draw fig, ax = pitch.draw(figsize=(16, 9)) bin_statistic = pitch.bin_statistic(df.x, df.y, statistic='count', bins=(25, 25)) bin_statistic['statistic'] = gaussian_filter(bin_statistic['statistic'], 1) pcm = pitch.heatmap(bin_statistic, ax=ax, cmap='hot', edgecolors='#22312b') cbar = fig.colorbar(pcm, ax=ax) TITLE_STR = 'Location of pressure events - 3 home games for Chelsea FC Women' title = fig.suptitle(TITLE_STR, x=0.4, y=0.98, fontsize=23)