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']] ############################################################################## # Custom colormap, font, and path effects # see the custom colormaps example for more ideas on setting colormaps pearl_earring_cmap = LinearSegmentedColormap.from_list( "Pearl Earring - 10 colors", ['#15242e', '#4393c4'], N=10) # fontmanager for google font (robotto) robotto_regular = FontManager() path_eff = [ path_effects.Stroke(linewidth=3, foreground='black'), path_effects.Normal() ] ############################################################################## # Plot positional heatmap # ----------------------- # setup pitch pitch = VerticalPitch(pitch_type='statsbomb', line_zorder=2, pitch_color='#22312b', line_color='white')
statistic='count', bins=bins) hm = pitch.heatmap(bs_heatmap, ax=axs['pitch'], 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=axs['pitch']) # title / endnote font = FontManager() # default is loading robotto font from google fonts axs['title'].text(0.5, 0.5, f'{team1} pass flow map vs {team2}', fontsize=25, fontproperties=font.prop, va='center', ha='center') axs['endnote'].text(1, 0.5, '@your_amazing_tag', fontsize=18, fontproperties=font.prop, va='center', ha='right')
Here we plot a pizza chart where the parameters have the same units, but the maximum is five instead of 100. """ import matplotlib.pyplot as plt from mplsoccer import PyPizza, FontManager ############################################################################## # Load some fonts # --------------- # We will use mplsoccer's FontManager to load some fonts from Google Fonts. # We borrowed the FontManager from the excellent # `ridge_map library <https://github.com/ColCarroll/ridge_map>`_. font_normal = FontManager(("https://github.com/google/fonts/blob/main/apache/roboto/static/" "Roboto-Regular.ttf?raw=true")) font_italic = FontManager(("https://github.com/google/fonts/blob/main/apache/roboto/static/" "Roboto-Italic.ttf?raw=true")) font_bold = FontManager(("https://github.com/google/fonts/blob/main/apache/roboto/static/" "Roboto-Medium.ttf?raw=true")) ############################################################################## # Different Units # --------------- # Till now we were plotting a percentile chart where the upper limit was 100. # Let's take another example where the lower limit is 0 and upper limit is 5. # The below code shows how to plot pizza-chart for such case. # parameter and value list params = ['Speed', 'Agility', 'Strength', 'Passing', 'Dribbles'] values = [5, 2, 4, 3, 1]
num_sub = num_players - 11 ############################################################################## # Setup the pitch, arrows, and get some images # add padding to the top so we can plot the titles, and raise the pitch lines pitch = Pitch(pad_top=10, line_zorder=2) # arrow properties for the sub on/off green_arrow = dict(arrowstyle='simple, head_width=0.7', connectionstyle="arc3,rad=-0.8", fc="green", ec="green") red_arrow = dict(arrowstyle='simple, head_width=0.7', connectionstyle="arc3,rad=-0.8", fc="red", ec="red") # a fontmanager object for using a google font fm_scada = FontManager(('https://github.com/googlefonts/scada/blob/main/fonts/ttf/' 'Scada-Regular.ttf?raw=true')) # Load the Club/ Statsbomb logos # these are the property of the respective clubs/ StatsBomb. BARCA_LOGO_URL = ('https://upload.wikimedia.org/wikipedia/en/thumb/4/47/' 'FC_Barcelona_%28crest%29.svg/142px-FC_Barcelona_%28crest%29.svg.png') DEPORTIVO_LOGO_URL = ('https://upload.wikimedia.org/wikipedia/en/thumb/f/f8/' 'Deportivo_Alaves_logo_%282020%29.svg/' '300px-Deportivo_Alaves_logo_%282020%29.svg.png') SB_LOGO_URL = 'https://raw.githubusercontent.com/statsbomb/open-data/master/img/statsbomb-logo.jpg' barca_logo = Image.open(urlopen(BARCA_LOGO_URL)) deportivo_logo = Image.open(urlopen(DEPORTIVO_LOGO_URL)) sb_logo = Image.open(urlopen(SB_LOGO_URL)) ############################################################################## # Plotting the Pass Maps
ax_opta = fig.add_axes( (0.05, 0.05, 0.4, 0.4 * FIGWIDTH / FIGHEIGHT / opta_pitch.ax_aspect)) opta_pitch.draw(ax=ax_opta) custom_pitch = VerticalPitch(pitch_type='custom', line_color='black', half=True, pitch_length=105, pitch_width=68, line_zorder=3) ax_custom = fig.add_axes( (0.55, 0.05, 0.4, 0.4 * FIGWIDTH / FIGHEIGHT / custom_pitch.ax_aspect)) custom_pitch.draw(ax=ax_custom) # draw the original event points fm = FontManager() # a mplsoccer fontmanager with the default Robotto font opta_pitch.scatter(x, y, s=250, marker='x', alpha=0.8, edgecolor='black', facecolor='#6778d0', ax=ax_opta) TEXT = ('The initial points are inside\n' 'the penalty area, six yard box,\n' 'and on the penalty-spot') _ = ax_text(50, 70, TEXT, va='center',
""" Example using refactored Radar.""" from mplsoccer import Radar, FontManager import matplotlib.pyplot as plt # fonts for the charts URL1 = ('https://github.com/googlefonts/SourceSerifProGFVersion/blob/master/' 'fonts/SourceSerifPro-Regular.ttf?raw=true') URL2 = ('https://github.com/googlefonts/SourceSerifProGFVersion/blob/master/' 'fonts/SourceSerifPro-ExtraLight.ttf?raw=true') font_params = FontManager(URL1) font_range = FontManager(URL2) # inputs params = [ "npxG", "Non-Penalty\n Goals", "xA", "Key\n Passes", "Through\n Balls", "Progressive\n Passes", "Shot-Creating\n Actions", "Goal-Creating\n Actions", "Dribbles\n Completed", "Pressure\n Regains", "Touches\nIn Box" ] values = [0.25, 0.42, 0.42, 3.47, 1.04, 8.06, 5.62, 0.97, 0.56, 5.14, 3.54] values_compare = [ 0.32, 0.00, 0.43, 3.50, 0.98, 7.72, 6.18, 0.98, 1.71, 4.88, 4.96 ] low = [0.08, 0.00, 0.10, 1.00, 0.60, 4.00, 3.00, 0.30, 0.30, 2.00, 2.00] high = [0.37, 0.60, 0.60, 4.00, 1.20, 10.00, 8.00, 1.30, 1.50, 5.50, 5.00] # radar comparison radar = Radar(params, low, high) fig, ax = radar.setup_axis() rings_inner = radar.draw_circles(ax=ax,
import matplotlib.patheffects as path_effects # get data df = read_event(f'{EVENT_SLUG}/7478.json', related_event_df=False, shot_freeze_frame_df=False, tactics_lineup_df=False)['event'] # get the team names team1, team2 = df.team_name.unique() # filter the dataset to completed passes for team 1 mask_team1 = (df.type_name == 'Pass') & (df.team_name == team1) & (df.outcome_name.isnull()) df_pass = df.loc[mask_team1, ['x', 'y', 'end_x', 'end_y', 'outcome_name']] # load a custom font from google fonts fm = FontManager('https://github.com/google/fonts/blob/main/ofl/sedgwickave/' 'SedgwickAve-Regular.ttf?raw=true') ############################################################################## # Plotting cybperpunk passes # -------------------------- LINEWIDTH = 1 # starting linewidth DIFF_LINEWIDTH = 1.2 # amount the glow linewidth increases each loop NUM_GLOW_LINES = 10 # the amount of loops, if you increase the glow will be wider # in each loop, for the glow, we plot the alpha divided by the num_glow_lines # I have a lower alpha_pass_line value as there is a slight overlap in # the pass comet lines when using capstyle='round' ALPHA_PITCH_LINE = 0.3 ALPHA_PASS_LINE = 0.15 # The colors are borrowed from mplcyberpunk. Try some of the following alternatives
############################################################################## # Plot Messi's first game as a false-9. pitch = VerticalPitch(line_color='#000009', line_zorder=2, pitch_color='white') fig, ax = pitch.draw(figsize=(4.4, 6.4)) hexmap = pitch.hexbin(df_false9.x, df_false9.y, ax=ax, edgecolors='#f4f4f4', gridsize=(8, 8), cmap=flamingo_cmap) ############################################################################## # Load a custom font. URL = 'https://github.com/googlefonts/roboto/blob/main/src/hinted/Roboto-Regular.ttf?raw=true' URL2 = 'https://github.com/google/fonts/blob/main/apache/roboto/static/Roboto-Bold.ttf?raw=true' robotto_regular = FontManager(URL) robboto_bold = FontManager(URL2) ############################################################################## # Load images. # Load the StatsBomb logo and Messi picture MESSI_URL = 'https://upload.wikimedia.org/wikipedia/commons/b/b8/Messi_vs_Nigeria_2018.jpg' messi_image = Image.open(urlopen(MESSI_URL)) SB_LOGO_URL = 'https://raw.githubusercontent.com/statsbomb/open-data/master/img/statsbomb-logo.jpg' sb_logo = Image.open(urlopen(SB_LOGO_URL)) ############################################################################## # Plot the chart again with a title. # We will use mplsoccer's grid function to plot a pitch with a title and endnote axes.
df_total = df_total.T df_total = df_total.divide(df_total.sum(axis=1), axis=0) * 100 ############################################################################## # Calculate the percentages for each team and sort so that the teams which press higher are last df[pressure_cols] = df[pressure_cols].divide(df[pressure_cols].sum(axis=1), axis=0) * 100. df.sort_values(['Att 3rd', 'Def 3rd'], ascending=[True, False], inplace=True) ############################################################################## # Get the StatsBomb logo and Fonts LOGO_URL = 'https://raw.githubusercontent.com/statsbomb/open-data/master/img/statsbomb-logo.jpg' sb_logo = Image.open(urlopen(LOGO_URL)) # a FontManager object for using a google font (default Robotto) fm = FontManager() # path effects path_eff = [path_effects.Stroke(linewidth=3, foreground='black'), path_effects.Normal()] ############################################################################## # Plot the percentages # setup a mplsoccer pitch pitch = Pitch(line_zorder=2, line_color='black', pad_top=20) # mplsoccer calculates the binned statistics usually from raw locations, such as pressure events # for this example we will create a binned statistic dividing # the pitch into thirds for one point (0, 0) # we will fill this in a loop later with each team's statistics from the dataframe bin_statistic = pitch.bin_statistic([0], [0], statistic='count', bins=(3, 1))
It shows how pitches stretch to fit pitches of a fixed dimension. More details are available in the Standardize data example. """ import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Polygon from mplsoccer import Pitch, VerticalPitch, FontManager from mplsoccer.quiver import arrows FIGWIDTH, FIGHEIGHT = 14, 10 FIGSIZE = (FIGWIDTH, FIGHEIGHT) FIG_ASPECT = FIGWIDTH / FIGHEIGHT fig = plt.figure(figsize=FIGSIZE) fm_rubik = FontManager(('https://github.com/google/fonts/blob/main/ofl/rubikmonoone/' 'RubikMonoOne-Regular.ttf?raw=true')) # layout specifications PAD = 1 pitch_spec = {'pad_left': PAD, 'pad_right': PAD, 'pad_bottom': PAD, 'pad_top': PAD, 'pitch_color': 'None'} pitch_width, pitch_length = 80, 105 pitch_width3, pitch_length3 = 60, 105 pitch_length4, pitch_width4 = 120, 68 pitch_length6, pitch_width6 = 85, 68 # define pitches (top left, top middle, top right, bottom left, bottom middle, bottom right) pitch1 = Pitch(pitch_type='custom', pitch_width=pitch_width, pitch_length=pitch_length, line_color='#b94e45', **pitch_spec) pitch2 = Pitch(pitch_type='statsbomb', **pitch_spec) pitch3 = Pitch(pitch_type='custom', pitch_width=pitch_width3, pitch_length=pitch_length3,
round_int=[False] * 11, num_rings=4, # the number of concentric circles (excluding center circle) # if the ring_width is more than the center_circle_radius then # the center circle radius will be wider than the width of the concentric circles ring_width=1, center_circle_radius=1) ############################################################################## # Load some fonts # --------------- # We will use mplsoccer's FontManager to load some fonts from Google Fonts. # We borrowed the FontManager from the excellent # `ridge_map library <https://github.com/ColCarroll/ridge_map>`_. URL1 = ('https://github.com/googlefonts/SourceSerifProGFVersion/blob/main/' 'fonts/SourceSerifPro-Regular.ttf?raw=true') serif_regular = FontManager(URL1) URL2 = ('https://github.com/googlefonts/SourceSerifProGFVersion/blob/main/' 'fonts/SourceSerifPro-ExtraLight.ttf?raw=true') serif_extra_light = FontManager(URL2) URL3 = ('https://github.com/google/fonts/blob/main/ofl/rubikmonoone/' 'RubikMonoOne-Regular.ttf?raw=true') rubik_regular = FontManager(URL3) URL4 = 'https://github.com/googlefonts/roboto/blob/main/src/hinted/Roboto-Thin.ttf?raw=true' robotto_thin = FontManager(URL4) URL5 = 'https://github.com/googlefonts/roboto/blob/main/src/hinted/Roboto-Regular.ttf?raw=true' robotto_regular = FontManager(URL5) URL6 = 'https://github.com/googlefonts/roboto/blob/main/src/hinted/Roboto-Bold.ttf?raw=true' robotto_bold = FontManager(URL6) ############################################################################## # Player Values