<jupyter_start><jupyter_text>Plot XG After MatchThe goal of this notebook is to create a time plot that shows the XG and actual goals for each team over the course of the match, after the match has been completed.It may be better to implement these visualizations on the frontend, but we can quickly prototype plots and return them as images from our server for completed matches on-demand.<jupyter_code>%matplotlib inline
import sys
sys.path.append("../")

from haxml.prediction import (
    generate_rows_demo,
    predict_xg_demo
)
from haxml.utils import (
    get_stadiums,
    load_match,
)
import joblib
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
MATCH = "-MOyZiwOkxMJwf-lNiT3"
STADIUM = "NAFL 1v1/2v2 Map v1"
MATCH = "-MOyZiwOkxMJwf-lNiT3"
STADIUM = "NAFL 1v1/2v2 Map v1"
model_name = "demo_logit"
demo_clf = joblib.load("../models/demo_logistic_regression.pkl")
stadiums = get_stadiums("../data/stadiums.json")
s = stadiums[STADIUM]
match = load_match(
    "../data/packed_matches/{}.json".format(MATCH),
    lambda m: predict_xg_demo(m, s, generate_rows_demo, demo_clf)
)
s = stadiums[STADIUM]
match = load_match(
    "../data/packed_matches/{}.json".format(MATCH),
    lambda m: predict_xg_demo(m, s, generate_rows_demo, demo_clf)
)
def get_xg_time_series(match):
    """
    Produces series for XG match time plot.
    Args:
        match: Inflated match data (dict).
    Returns:
        Tuple of (time, ags_red, ags_blue, xgs_red, xgs_blue).
    """
    time = []
    ags_red = []
    ags_blue = []
    xgs_red = []
    xgs_blue = []
    ag_red = 0
    ag_blue = 0
    xg_red = 0
    xg_blue = 0
    time.append(0)
    ags_red.append(ag_red)
    ags_blue.append(ag_blue)
    xgs_red.append(xg_red)
    xgs_blue.append(xg_blue)
    for kick in match["kicks"]:
        if kick["type"] == "goal":
            if kick["fromTeam"] == "red":
                ag_red += 1
            else:
                ag_blue += 1
        elif kick["type"] == "own_goal":
            if kick["team"] == "red":
                ag_blue += 1
            else:
                ag_red += 1
        if kick["fromTeam"] == "red":
            xg_red += kick["xg"]
        else:
            xg_blue += kick["xg"]
        time.append(kick["time"])
        ags_red.append(ag_red)
        ags_blue.append(ag_blue)
        xgs_red.append(xg_red)
        xgs_blue.append(xg_blue)
    time.append(match["score"]["time"])
    ags_red.append(ag_red)
    ags_blue.append(ag_blue)
    xgs_red.append(xg_red)
    xgs_blue.append(xg_blue)
    return (
        time,
        ags_red,
        ags_blue,
        xgs_red,
        xgs_blue
    )
def plot_xg_time_series(match):
    """
    Plots XG match time series for a match.
    Args:
        match: Inflated match data (dict).
    Returns:
        Tuple (fig, ax).
    """
    fig = Figure()
    ax = fig.add_subplot(1, 1, 1)
    xg_time_ser = get_xg_time_series(match)
    time, ags_red, ags_blue, xgs_red, xgs_blue = xg_time_ser
    ax.plot(time, ags_red, color="red", linestyle="-", label="Red Actual")
    ax.plot(time, xgs_red, color="red", linestyle="--", label="Red XG")
    ax.plot(time, ags_blue, color="blue", linestyle="-", label="Blue Actual")
    ax.plot(time, xgs_blue, color="blue", linestyle="--", label="Blue XG")
    title = "Final Score: {} Won {}-{}\n{}"
    red_score = match["score"]["red"]
    blue_score = match["score"]["blue"]
    winner = "Red" if red_score > blue_score else "Blue"
    stadium_name = match["stadium"]
    ax.set_title(title.format(winner, red_score, blue_score, stadium_name))
    ax.set_xlabel("Match Time (secs)")
    ax.set_ylabel("Goals")
    ax.legend()
    return fig, ax
fig, ax = plot_xg_time_series(match)
ax.set_title("{}\nXG Model: {}".format(ax.title.get_text(), model_name))
fig.set_size_inches(10, 6)
fig<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1327088212334114, 'fraction_numerical': 0.00702576112412178, 'mean_word_length': 2.9224489795918367, 'pattern_counts': {'":': 5, '<': 5, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '534131', 'license': 'MIT', 'n_tokens_mistral': 1451, 'n_tokens_neox': 1412, 'n_words': 319, 'path': 'notebooks/plot_xg_after_match.ipynb', 'repo_name': 'vingkan/haxml', 'size': '3843'}