Каков наилучший способ визуализации личных встреч? - PullRequest
1 голос
/ 24 февраля 2020

У меня фрейм данных выглядит следующим образом:

A = pd.DataFrame({'team':[1,2,3,2,1,1,3,4,1,2], 'opp_team':[2,1,2,3,3,4,1,1,2,1], 'result':[1,0,1,0,1,1,0,0,1,0]})

Столбец результата содержит 1, представляющий победу, и 0, представляющий поражение. Я хочу выяснить, как лучше всего представить личный рекорд на графике.

Я думал о парном сюжете, но думаю, что он не сработает, потому что он не покажет счет победы. и победить. В приведенном выше примере команда 1 играла против команды 2 2 раза и выиграла оба. Итак, на графике также должен быть показан счет.

Пожалуйста, дайте мне знать, если есть эффективный способ.

Спасибо.

1 Ответ

2 голосов
/ 24 февраля 2020

Просто покажите их на 2 отдельных графиках, 1 график показывает общее количество личных встреч, а другой показывает общий коэффициент выигрыша одной команды против другой (коэффициент победы другой команды = коэффициент поражения команды ).

Чтобы сделать это, я думаю, что фрейм данных нужно реструктурировать так, чтобы он показывал только 1 идентификатор игры на строку. Чтобы упростить группировку, сортируйте team и opp_team таким образом, чтобы индекс для team всегда был меньше, чем индекс для opp_team

. Я создал образец набора данных, как я хотел бы суммируйте и нанесите на карту для справки:

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

def generate_data(num_data=100, num_teams=4):

    team = np.random.randint(1,1 + num_teams,num_data)
    opp_team = np.random.randint(1,1 + num_teams,num_data)

    while len(opp_team[opp_team == team]) > 0:
        opp_team[opp_team == team] = np.random.randint(1,1 + num_teams,len(opp_team[opp_team == team]))

    results = np.round(np.random.rand(100))    

    return team, opp_team, results

def reorder_team(team, opp_team, result):

    if team > opp_team:
        team, opp_team = opp_team, team
        result = 1 - result

    return team, opp_team, result

# Generate data and get summary by team match-ups
team, opp_team, results = generate_data()

df = pd.DataFrame(data={'team':team,'opp_team':opp_team,'results':results}, dtype='int')
df = pd.DataFrame(df.apply(lambda x : reorder_team(x['team'], x['opp_team'], x['results']),axis=1).to_list(), 
                  columns=df.columns)
df[['team','opp_team']] = 'Team ' + df[['team','opp_team']].astype(str)

df_summary = df.groupby(['team','opp_team']).agg(['sum','count'])
df_summary.columns = ['wins', 'total']
df_summary.reset_index(inplace=True)
df_summary['team_winrate'] = (df_summary['wins'] / df_summary['total'])
df_summary['opp_team_winrate'] = 1 - df_summary['team_winrate']

, что дает:

enter image description here

, и вы можете построить их, используя следующие скрипт (или написать свой, используя свою любимую библиотеку):

fig, (ax_count, ax_win) = plt.subplots(1,2, figsize=(12,6))

y_locs = list(range(len(df_summary)))

ax_count.barh(y_locs, width=df_summary['total'], color='tab:gray')
ax_count.set_yticks(y_locs)
ax_count.set_yticklabels(df_summary['team'] + ' VS ' + df_summary['opp_team'])
ax_count.set_title('Total No. of Match Ups')
ax_count.set_xticks([])

for loc in ['top','left','right','bottom']:
    ax_count.spines[loc].set_visible(False)

for p in ax_count.patches:
    ax_count.annotate(f'{p.get_width()}',
                      (p.get_x() + p.get_width(), p.get_y() + p.get_height()/2.), 
                      ha='right', va='center', xytext=(-5,0), textcoords='offset points', 
                      color='white',fontweight='heavy')

ax_win.barh(y_locs, width=df_summary['team_winrate'], color='tab:blue')
ax_win2 = ax_win.twinx()
ax_win2.barh(y_locs, width=df_summary['opp_team_winrate'], 
             left=df_summary['team_winrate'], color='tab:red')

ax_win.set_yticks(y_locs)
ax_win.set_yticklabels(df_summary['team'])
ax_win2.set_yticks(y_locs)
ax_win2.set_yticklabels(df_summary['opp_team'])

ax_win.set_xlim(0,1)
ax_win.set_title('Winning Rate')
ax_win.set_xticks([])

for loc in ['top','left','right','bottom']:
    ax_win.spines[loc].set_visible(False)
    ax_win2.spines[loc].set_visible(False)

for p in ax_win.patches:
    ax_win.annotate(f'{p.get_width() * 100 :.0f} %',
                      (0, p.get_y() + p.get_height()/2.), 
                      ha='left', va='center', xytext=(10,0), textcoords='offset points', 
                      color='white',fontweight='heavy')

    ax_win2.annotate(f'{(1 - p.get_width()) * 100 :.0f} %',
                      (1, p.get_y() + p.get_height()/2.), 
                      ha='right', va='center', xytext=(-10,0), textcoords='offset points', 
                      color='white',fontweight='heavy')

plt.show()

enter image description here

...