「일정군」의 데이터로부터 전적표를 matplotlib로 작성해 본다

개요



표 형식으로 대전 예정이나 결과(〇,△,●)를 가시화한 것을 전적표라고 합니다. 단지 이것만은 뭐라고 느끼기 때문에, 실제의 그래픽을 보여 드리겠습니다.

  • 분데스리가 일본어판(Twitter:@Bundesliga_JP)에서 인용

  • 이 표의 견해는 X축이 어웨이에서 대전하는 상대, Y축이 홈에서 대전하는 상대를 나타내고 있습니다.
    이러한 테이블을 「일정군」의 데이터로부터, matplotlib (을)를 사용해 작성합니다. 정평의 가시화 수법으로부터 하면 크게 빗나가지만, 이런 일도 할 수 있는 일례입니다.

    원본 데이터


  • '일정군'의 결과를 스크래핑

  • 데이터 가공



    fixturetable.py
    game_result = pd.read_csv("../csv/game_result_all_2020_v2.csv", encoding="utf-8")
    # J1のチーム名リスト(北から)2020年版
    team = ["札幌","仙台","鹿島","浦和","柏","FC東京","川崎F","横浜FM","横浜FC","湘南",
            "清水","名古屋","G大阪","C大阪","神戸","広島","鳥栖","大分"]
    # J1のみ抽出し新しいデータフレーム作成
    game_J1_tmp = game_result[game_result["大会"] == "J1"]
    


    아직 개막하고 있지 않기 때문에 「스코어・입장자수・home_g・away_g・결과」에는 데이터가 없습니다. 이번 표에는 관계 없기 때문에 무시하고 괜찮습니다.

    fixturetable.py
    # 結合元の空データフレーム作成
    game_J1 = pd.DataFrame(index=team, columns=team)
    
    for i, t in enumerate(team):
        # [1]チーム単位にそれぞれの対戦相手と節と結果を抽出する
        team_tmp = game_J1_tmp.loc[game_J1_tmp["ホーム"] == t, ["アウェイ", "sec", "結果"]]
        # [2]取得したデータのindexをリセットする
        team_tmp.reset_index(inplace=True, drop=True)
        # [3]抽出条件のチーム分をsec:99で追加する
        team_tmp.loc[17,:] = [t, 99, -1]
        # [4]北からチーム順序データを追加する
        team_tmp["order"] = team_tmp["アウェイ"].apply(lambda x: team.index(x) if x in team else -1)
        # [5]北からチームに並び替える
        team_tmp = team_tmp.sort_values("order")
    
        # [6]最終形のデータフレームの行(抽出条件のチーム)に展開する。
        for x in range(len(team_tmp)):
            game_J1.iloc[i, x] = team_tmp.at[team_tmp.index[x],"sec"]
    

    1 팀 단위로 각각의 대전 상대와 절과 결과를 추출한다


    2 검색된 데이터의 index 재설정


    3 추출 조건의 팀분을 sec:99로 추가


    4 북쪽에서 팀 순서 데이터 추가


    5 북쪽에서 팀으로 정렬
    6 최종 형태의 데이터 프레임의 행 (추출 조건의 팀)에 전개한다.


    이것이 데이터의 최종 형태입니다. 이것을 그래프에 그립니다.

    fixturetable.py
    plt.rcParams["font.family"] = "IPAexGothic"
    
    fig = plt.figure(figsize=(6,6),dpi=144)
    ax1 = fig.add_subplot(111)
    
    teams = np.arange(len(team)+1)
    h, v = 0.5, 0.5
    
    ax1.set_ylim(18, 0)
    ax1.set_xticks(teams)
    ax1.set_yticks(teams)
    ax1.xaxis.tick_top()
    ax1.set_xticklabels(team, rotation=90)
    ax1.set_yticklabels(team)
    
    ax1.grid(True)
    ax1.tick_params(axis="both", which="both", length=0)
    
    # 開催節の表示と対戦のないマスの着色
    for k, t in enumerate(team):
        for i in range(18):
            if game_J1.at[game_J1.index[i], t] == 99:
                _ = patches.Rectangle(xy=(k, i), width=1.0, height=1.0, color="0.8")
                ax1.add_patch(_)
            else:
                ax1.text(k+h, i+v, game_J1.at[game_J1.index[i], t], size=12, color = "k", ha="center", va="center")
    
    ax1.set_title("2020明治安田生命J1リーグ戦績表", fontsize=16)
    txt = "引用元:JLeague Data Site"
    fig.text(.9, .1, txt, fontsize=10, horizontalalignment="right")
    txt3 = str(update) + "更新"
    fig.text(.9, .95, txt3, fontsize=10, horizontalalignment="right")
    
    #fig.tight_layout()
    plt.savefig("../img/J1fixturetable_noemblem_2020.png", bbox_inches="tight")
    

    그래프 작성의 포인트는 간단합니다.
    * 그리드 표시
    * 그 안에 절수를 텍스트로 그리기
    * 절수가 「99」의 경우는 사각형으로 회색의 음영을 그린다



    2019년 전적표



    ※단, 이 표는 X축이 홈팀, Y축이 어웨이팀입니다. (지금, 실수를 깨닫는다)


    남은 과제


  • 서두의 분데스리가와 같이 팀 로고를 X축, Y축에 배치해 묘화하고 싶었지만, 대폭으로 어긋나 묘화 되었기 때문에 팀명의 문자열 변경했다.
  • 팀 이름이 그리드의 가운데에서 그리드 사이의 가운데로 변경하고 싶지만 방법을 알지 못했습니다.
  • 좋은 웹페이지 즐겨찾기