import pandas as pd
import altair as alt
from load_decks import load_decks, deck_card_colors
raw_decks = load_decks()
0 25 50 75 100 125 150 175 200 225 250 275 300 325 350 375 400 425 450 475 500 525 550 575 600 625 650 675
decks = pd.DataFrame([deck_card_colors(d) for d in raw_decks if d['cards'] is not None]).set_index('id')
for c in 'WUBRG':
decks[c + 'd'] = decks[c] >= 5
decks['player'].nunique()
166
decks['primary_color'] = decks[list('WUBRG')].idxmax(axis=1)
def has_card(deck_id, card_name):
deck = next(deck for deck in raw_decks if deck['id'] == deck_id)
return any(card['card']['name'] == card_name for card in deck['cards'])
decks['hoof?'] = decks.apply(lambda row: has_card(row.name, 'Craterhoof Behemoth'), axis=1)
decks['shatter?'] = decks.apply(lambda row: has_card(row.name, 'Shatter the Sky'), axis=1)
decks['cast?'] = decks.apply(lambda row: has_card(row.name, 'Cast Down'), axis=1)
decks['ecd?'] = decks.apply(lambda row: has_card(row.name, 'Elspeth Conquers Death'), axis=1)
completed_decks = decks[(decks['match_wins'] + decks['match_losses']) == 5]
completed_decks.count()
match_wins 416 match_losses 416 player 416 resigned 416 creation_date 416 W 416 U 416 B 416 R 416 G 416 Wd 416 Ud 416 Bd 416 Rd 416 Gd 416 primary_color 416 hoof? 416 shatter? 416 cast? 416 ecd? 416 dtype: int64
416 / (4 * 7 - 1)
15.407407407407407
matches = set((match['winner']['id'], match['loser']['id']) for deck in raw_decks for match in deck['matches'])
def mtg_colors(name, color_names=list('WUBRG')):
return alt.Color(name, scale={'domain': color_names, 'range': ['#fffcda', '#ace2fa', '#ccc2c0', '#f8aa92', '#9dd2af']}, legend=None)
alt.Chart(completed_decks[['player', 'primary_color']]).mark_bar().encode(
x=alt.X('player:N', sort='-y', axis=None),
y=alt.Y('count():Q', title='Completed League Runs'),
color=mtg_colors('primary_color:N')
).properties(width='container', title='Completed League Runs per Player (with Primary Color)').save('jmp_league_completions.json')
(completed_decks.groupby('player').count()['resigned'] >= 10).sum()
13
deck_colors_weekly = completed_decks.groupby(pd.Grouper(key='creation_date', freq='7d'))[[c + 'd' for c in 'WUBRG']].apply(lambda group: group.sum() / group.count()).reset_index().melt(id_vars=['creation_date'])
alt.Chart(deck_colors_weekly).mark_bar().encode(
x=alt.X('variable:N', axis=None),
y=alt.Y('value:Q', title='Fraction of Decks'),
color=mtg_colors('variable:N', color_names=['Wd', 'Ud', 'Bd', 'Rd', 'Gd']),
column=alt.Column('creation_date:O', title='Week Start', header=alt.Header(format='%d %b', formatType='time', orient='bottom', titlePadding=0))
).properties(
width=155,
height=200,
title='Weekly Breakdown of Colors in All Completed Runs',
).configure_title(anchor='middle').save('jmp_weekly_breakdown_completed.json')
deck_colors_weekly = completed_decks[completed_decks['match_wins'] >= 3].groupby(pd.Grouper(key='creation_date', freq='7d'))[[c + 'd' for c in 'WUBRG']].apply(lambda group: group.sum() / group.count()).reset_index().melt(id_vars=['creation_date'])
alt.Chart(deck_colors_weekly).mark_bar().encode(
x=alt.X('variable:N', axis=None),
y=alt.Y('value:Q', title='Fraction of Decks'),
color=mtg_colors('variable:N', color_names=['Wd', 'Ud', 'Bd', 'Rd', 'Gd']),
column=alt.Column('creation_date:O', title='Week Start', header=alt.Header(format='%d %b', formatType='time', orient='bottom', titlePadding=0))
).properties(
width=155,
height=200,
title='Weekly Breakdown of Colors in w/ 3+ Wins',
).configure_title(anchor='middle').save('jmp_weekly_breakdown_winning.json')
deck_cards_weekly = completed_decks[completed_decks['match_wins'] >= 3].groupby(pd.Grouper(key='creation_date', freq='7d'))[['ecd?', 'hoof?', 'shatter?', 'cast?']].apply(lambda group: group.sum() / group.count()).reset_index().melt(id_vars=['creation_date'])
alt.Chart(deck_cards_weekly.replace({
'ecd?': "Elspeth Conquers Death",
'hoof?': "Craterhoof Behemoth",
'cast?': "Cast Down",
'shatter?': "Shatter the Sky"
})).mark_bar().encode(
x=alt.X('variable:N', title=None),
y=alt.Y('value:Q', title='Fraction of Decks'),
column=alt.Column('creation_date:O', title='Week Start', header=alt.Header(format='%d %b', formatType='time', orient='bottom', titlePadding=0))
).properties(
width=155,
height=200,
title='Weekly Breakdown of Hoof and Removal',
).configure_title(anchor='middle')#.save('jmp_weekly_breakdown_removal.json')
matches = set((match['winner']['id'], match['loser']['id'], match['date']) for deck in raw_decks for match in deck['matches'])
matches = pd.DataFrame(matches, columns=['winner', 'loser', 'date'])
matches['date'] = pd.to_datetime(matches['date'])
matches.dtypes
winner int64 loser int64 date datetime64[ns, UTC] dtype: object
alt.Chart(matches).mark_bar(tooltip=True).encode(
x=alt.X('date:T', timeUnit='hours', title="Time of Day (Local Time)"),
y=alt.Y('count()', title="# of Matches")
).properties(
width='container',
title='League Match Play Times'
).save('jmp_play_hours.json')
alt.Chart(matches).mark_bar(tooltip=True).encode(
x=alt.X('monthdate(date)', title="Date"),
y=alt.Y('count()', title="# of Matches Played"),
).properties(
width='container',
title='League Match Play Dates'
).save('jmp_play_dates.json')