%reload_ext pretty_jupyter
%%jinja markdown
<style>
    div.main-container {width:98%;max-width:100%;}   
    .btn {display:none;}    
    .col-md-3 {width:20%;}   
    .col-md-9 {width:80%;}
    h2 {margin-top:30px;}
    .tocify-extend-page {height: 50px !important;}
</style>
%%html
<head>
   <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
from mpl_toolkits.axes_grid1 import ImageGrid
from itables import init_notebook_mode, show
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import matplotlib.pyplot as plt
import plotly.express as px
from plotly import tools
import seaborn as sns
import pandas as pd
import numpy as np
import datetime
import warnings
import os

warnings.simplefilter(action='ignore', category=FutureWarning)
init_notebook_mode(all_interactive=False)
pd.set_option('display.max_columns', 50)
files = sorted(["covers/"+str(file) for file in os.listdir("covers") if ".webp" in file])
images = [plt.imread(images) for images in files]
fig = plt.figure(figsize=(15,15))
grid = ImageGrid(fig, 111,nrows_ncols=(8,9),axes_pad=0.1)
for ax, im in zip(grid, images):
    ax.imshow(im)
plt.show()

The Schedule

order = ['RL','WS','MT','TL','JP','RW','MJ','SF','RS']
album_count = len(images) - 2
current_turn = (album_count % 9) + 1
order = order[current_turn:] + order[:current_turn]
started = datetime.datetime(2024, 2, 5).date()
time_elapsed = datetime.timedelta(weeks=album_count+6)
one_week = datetime.timedelta(weeks=1)
current_week = started + time_elapsed

schedule = pd.DataFrame({'From':[order[0],order[1],order[2],order[3]],
                         'Album #':[album_count,album_count+1,album_count+2,album_count+3],
                         'Week Of':[current_week,current_week+one_week,current_week+(2*one_week),current_week+(3*one_week)]},
                         index=['This Week','Next Week','Coming Up','Next Month'])
schedule['Week Of'] = schedule['Week Of'].apply(lambda date: date.strftime('%d/%m'))

show(schedule)
From Album # Week Of
Loading... (need help?)
albums = pd.read_csv('albums.csv')
scores = pd.read_csv('scores.csv')
# Retrospective score changes
scores.at[5,'MT'] = 8
scores.at[(1,9),'MT'] = 3
scores.at[2,'JP'] = 8
scores.at[13,'MJ'] = 5.75
scores.at[25,'TL'] = 7.5
albums[['EDA','POC','Group']] = albums[['EDA','POC','Group']].astype(bool)
albums[['From','Genre','Decade','Origin','Gender']] = albums[['From','Genre','Decade','Origin','Gender']].astype('category')

scores.iloc[:,1:] = scores.iloc[:,1:].astype(float)
scores['AVG'] = scores.iloc[:,1:10].mean(axis=1).round(decimals=2)
scores['MED'] = scores.iloc[:,1:10].median(axis=1).round(decimals=2)
scores['MAX'] = scores.iloc[:,1:10].max(axis=1).round(decimals=2)
scores['MIN'] = scores.iloc[:,1:10].min(axis=1).round(decimals=2)
scores['SUM'] = scores.iloc[:,1:10].sum(axis=1).round(decimals=2)
scores['STD'] = scores.iloc[:,1:10].std(axis=1).round(decimals=2)
players = list(scores.columns[1:10])
players_trimmed = players[:]
players_trimmed.pop(4)

aggs = list(scores.columns[10:])

scores_players = scores.loc[:,(["#"]+players)]
scores_aggs = scores.loc[:,(["#"]+aggs)]

master = pd.merge(left=albums,right=scores,how='inner')

Get the Tables!

Album Details

albums.index+=1
show(albums.iloc[:,1:])
# From Artist Album Genre Year Decade Mins Group EDA Origin Gender POC
Loading... (need help?)

Individual Scores

combined = pd.merge(left=albums.iloc[:,1:5],right=scores_players,how='inner')
combined.index+=1
combined = combined.iloc[:,:].style \
                   .background_gradient(subset=players, cmap='Blues') \
                   .format(precision=2)

show(combined.map(lambda x: 'color: transparent; background-color: transparent' if pd.isnull(x) else ''))
# From Artist Album JP MJ MT RL RS RW SF TL WS
66 JP N.E.R.D. In Search Of... nan 6.75 7.50 nan nan 6.50 nan 6.25 6.00
65 TL Janelle Monáe Dirty Computer nan 7.00 5.75 nan nan 8.00 6.75 nan 7.00
64 MT Idris Muhammad Turn This Mutha Out 7.00 7.00 nan nan nan 7.00 7.00 7.00 7.00
63 WS Thundercat Drunk 5.00 5.75 6.75 nan nan 4.50 nan 4.25 nan
62 RL Gallant Ology nan 6.50 5.00 nan nan 7.00 nan 7.00 6.25
61 SF Led Zeppelin Led Zeppelin IV 6.75 7.00 5.75 nan nan 7.00 nan 5.75 7.00
60 MJ Basement Jaxx Remedy nan nan 6.75 nan nan 6.00 nan 6.00 6.00
59 RW Simon & Garfunkel Bridge Over Troubled Water nan 6.75 5.25 nan nan nan nan 7.75 7.00
58 JP Friendly Fires Friendly Fires nan 6.75 7.50 nan nan 6.00 nan 6.00 5.50
57 TL Peter Gabriel So 5.50 7.75 6.75 nan nan 7.75 nan nan 7.50
56 MT Skrillex Fuck U Skrillex 6.75 6.50 nan 7.75 nan 7.00 nan 6.50 6.75
55 WS Frank Ocean Blonde 5.00 6.50 6.25 nan nan 5.50 nan 6.75 nan
54 RL Jay Bennett Deeper Shades of Euphoria nan 5.75 5.50 nan nan 6.00 nan 6.25 6.00
53 SF The Mad Capsule Markets Osc-Dis nan 6.75 6.75 6.00 nan 5.75 nan 6.75 4.00
52 MJ The Naked and Famous Passive Me, Aggressive You nan nan 8.00 7.75 nan 6.00 nan 7.00 7.25
51 RW Shania Twain Come On Over 5.75 7.25 7.00 7.00 nan nan nan 7.00 6.50
50 JP The Temper Trap Conditions nan 6.75 6.00 6.75 nan 5.75 nan 5.50 5.75
49 TL Children of Bodom Hate Crew Deathroll nan 6.75 6.75 8.00 nan 6.25 7.50 nan 9.00
48 MT Fontaines D.C. Skinty Fia nan 6.00 nan 4.00 nan 6.00 5.50 6.75 6.00
47 WS Spiritbox Eternal Blue nan 7.00 6.25 6.25 nan 6.50 6.50 6.75 nan
46 RL Cœur de pirate Cœur de pirate nan 6.50 7.25 nan nan 6.75 7.00 7.25 6.75
45 SF Sum 41 All Killer No Filler nan 7.50 7.50 8.00 nan 7.50 nan 7.50 8.00
44 MJ Run the Jewels Run the Jewels nan nan 5.25 7.00 nan 7.00 5.25 6.50 7.00
43 RW Highly Suspect Mister Asylum nan 7.25 6.75 6.75 nan nan 7.00 7.25 8.00
42 JP Raleigh Ritchie You're A Man Now, Boy nan 6.75 4.50 6.25 nan 7.00 6.00 6.75 4.50
41 TL Jack's Mannequin Everything in Transit nan 6.75 5.75 9.00 nan 7.00 8.25 nan 7.00
40 MT SBTRKT SBTRKT nan 6.50 nan 6.50 nan 6.25 5.50 5.25 5.25
39 WS Benjamin Clementine At Least For Now nan 7.25 6.00 5.00 nan 5.50 6.25 6.00 nan
38 RL Porter Robinson Worlds nan 6.75 7.75 nan nan 7.25 6.50 7.50 7.25
37 SF Suburban Legends Dance Like Nobody's Watching nan 6.00 5.00 6.25 nan 6.75 nan 5.00 5.75
36 MJ House of Protection GALORE nan nan 7.75 6.50 nan 7.50 7.25 6.50 7.00
35 RW Dolly Parton Jolene nan 6.75 5.75 7.00 nan nan 7.00 7.25 6.75
34 JP The Backseat Lovers Elevator Days nan 6.25 6.25 6.25 nan 6.25 6.50 6.00 6.75
33 TL Funeral for a Friend Seven Ways to Scream Your Name nan 6.75 6.50 6.00 nan 6.75 7.25 nan 7.75
32 RS Fightstar They Liked You Better When You Were Dead 7.00 6.50 5.75 7.25 nan 6.00 6.25 6.50 6.00
31 MT Parcels Hideout nan 6.50 nan 6.25 nan 5.75 6.50 5.75 6.25
30 WS Devil Sold His Soul Belong ╪ Betray nan 6.75 6.25 7.75 nan 6.25 7.00 8.00 nan
29 RL Bad Rabbits Stick Up Kids nan 6.50 5.75 nan nan 6.75 6.75 5.50 5.50
28 SF Foo Fighters Foo Fighters 6.00 7.50 4.50 5.50 nan 6.00 nan 7.00 6.50
27 RS Alien Ant Farm truANT 6.50 6.50 7.00 6.00 nan 5.75 6.00 5.50 4.50
26 MJ Talking Heads Remain in Light 7.00 nan 7.00 6.25 nan 6.00 6.50 7.50 7.25
25 RW Griff Vertigo 6.50 6.50 5.50 7.50 nan nan 6.25 6.50 6.00
24 JP Childish Gambino Bando Stone & The New World nan 6.75 6.00 4.50 nan 6.25 6.00 7.75 7.75
23 TL Chicane Giants 7.00 6.00 5.50 8.00 nan 6.50 5.50 nan 7.75
22 MT Tom Misch Geography 6.75 6.50 nan 6.75 nan 6.00 6.75 6.00 7.25
21 WS Sleep Token Take Me Back to Eden nan 7.00 5.25 5.50 nan 6.00 5.25 4.50 nan
20 RL Joe Satriani Surfing with the Alien 5.50 6.00 7.00 nan nan 5.25 5.75 5.00 5.00
19 RS The Wildhearts Earth vs the Wildhearts 6.00 6.25 5.75 4.50 nan 4.50 6.00 4.00 4.00
18 RS Beartooth The Surface 6.75 7.50 6.50 7.50 nan 8.00 7.50 7.00 7.50
17 SF As December Falls As December Falls 6.00 6.25 3.75 6.50 nan 6.00 nan 5.75 6.00
16 MJ MisterWives Our Own House 6.50 nan 5.75 8.25 nan 8.00 6.25 6.75 7.50
15 RW Live Throwing Copper 5.75 6.25 5.75 4.75 nan nan 6.50 6.00 5.00
14 JP Post Malone Hollywood's Bleeding nan 5.75 4.25 5.25 nan 6.00 4.75 5.25 4.50
13 TL Grimes Art Angels 6.00 7.25 6.00 8.50 nan 7.50 4.75 nan 7.50
12 MT IDLES Joy as an Act of Resistance 7.00 6.75 nan 5.25 nan 5.75 6.75 6.50 6.50
11 WS Every Time I Die Radical 6.25 7.00 6.75 3.00 nan 5.75 6.50 7.50 nan
10 RL Sigur Rós ( ) 5.50 5.75 3.00 nan nan 5.25 6.50 7.50 6.50
9 SF Newton Faulkner Hand Built by Robots 5.50 6.00 3.50 6.50 nan 5.75 nan 3.75 4.50
8 RS Linkin Park The Hunting Party 5.00 6.75 3.00 6.25 nan 6.75 6.75 6.75 3.00
7 MJ Electric Six Fire 6.75 nan 8.50 4.75 nan 7.75 7.25 6.50 7.00
6 RW Tracy Chapman Tracy Chapman 7.50 7.50 8.00 7.50 nan nan 7.25 7.25 7.50
5 JP Kendrick Lamar Mr. Morale & the Big Steppers nan 7.00 4.75 5.00 nan 4.75 4.25 6.75 6.00
4 TL Talk Talk The Colour of Spring 6.75 6.50 5.50 7.25 nan 6.00 7.00 nan 6.75
3 MT Jungle Volcano 8.00 6.00 nan 7.00 nan 5.75 5.75 5.75 6.75
2 WS The Black Queen Fever Daydream 4.75 6.75 3.00 4.25 nan 6.00 5.50 5.25 nan
1 RL M83 Before the Dawn Heals Us 5.75 6.00 5.00 nan 5.00 6.50 6.00 6.25 6.00

Summary Scores

combined_aggs = pd.merge(left=albums.iloc[:,1:7],right=scores_aggs,how='inner')
combined_aggs.index+=1
combined_aggs = combined_aggs.iloc[:,:].style \
                             .background_gradient(subset=['AVG','MAX'], cmap='Greens') \
                             .format(precision=2)

show(combined_aggs.map(lambda x: 'color: transparent; background-color: transparent' if pd.isnull(x) else ''))
# From Artist Album Genre Year AVG MED MAX MIN SUM STD
66 JP N.E.R.D. In Search Of... Hip Hop 2001 6.60 6.50 7.50 6.00 33.00 0.58
65 TL Janelle Monáe Dirty Computer R&B 2018 6.90 7.00 8.00 5.75 34.50 0.80
64 MT Idris Muhammad Turn This Mutha Out Jazz 1977 7.00 7.00 7.00 7.00 42.00 0.00
63 WS Thundercat Drunk R&B 2017 5.25 5.00 6.75 4.25 26.25 1.02
62 RL Gallant Ology R&B 2016 6.35 6.50 7.00 5.00 31.75 0.82
61 SF Led Zeppelin Led Zeppelin IV Rock 1971 6.54 6.88 7.00 5.75 39.25 0.62
60 MJ Basement Jaxx Remedy Electronic 1999 6.19 6.00 6.75 6.00 24.75 0.38
59 RW Simon & Garfunkel Bridge Over Troubled Water Folk Rock 1970 6.69 6.88 7.75 5.25 26.75 1.05
58 JP Friendly Fires Friendly Fires Indie Rock 2008 6.35 6.00 7.50 5.50 31.75 0.78
57 TL Peter Gabriel So New Wave 1986 7.05 7.50 7.75 5.50 35.25 0.96
56 MT Skrillex Fuck U Skrillex Dubstep 2025 6.88 6.75 7.75 6.50 41.25 0.47
55 WS Frank Ocean Blonde R&B 2016 6.00 6.25 6.75 5.00 30.00 0.73
54 RL Jay Bennett Deeper Shades of Euphoria Dance 2003 5.90 6.00 6.25 5.50 29.50 0.29
53 SF The Mad Capsule Markets Osc-Dis Digital Hardcore 1999 6.00 6.38 6.75 4.00 36.00 1.07
52 MJ The Naked and Famous Passive Me, Aggressive You Indietronica 2010 7.20 7.25 8.00 6.00 36.00 0.78
51 RW Shania Twain Come On Over Country Pop 1997 6.75 7.00 7.25 5.75 40.50 0.55
50 JP The Temper Trap Conditions Rock 2009 6.08 5.88 6.75 5.50 36.50 0.54
49 TL Children of Bodom Hate Crew Deathroll Metal 2003 7.38 7.12 9.00 6.25 44.25 1.01
48 MT Fontaines D.C. Skinty Fia Indie Rock 2022 5.71 6.00 6.75 4.00 34.25 0.93
47 WS Spiritbox Eternal Blue Metalcore 2021 6.54 6.50 7.00 6.25 39.25 0.29
46 RL Cœur de pirate Cœur de pirate Pop 2008 6.92 6.88 7.25 6.50 41.50 0.30
45 SF Sum 41 All Killer No Filler Pop Punk 2001 7.67 7.50 8.00 7.50 46.00 0.26
44 MJ Run the Jewels Run the Jewels Hip Hop 2013 6.33 6.75 7.00 5.25 38.00 0.86
43 RW Highly Suspect Mister Asylum Rock 2015 7.17 7.12 8.00 6.75 43.00 0.47
42 JP Raleigh Ritchie You're A Man Now, Boy R&B 2016 5.96 6.25 7.00 4.50 41.75 1.06
41 TL Jack's Mannequin Everything in Transit Pop Rock 2005 7.29 7.00 9.00 5.75 43.75 1.16
40 MT SBTRKT SBTRKT Electronic 2011 5.88 5.88 6.50 5.25 35.25 0.61
39 WS Benjamin Clementine At Least For Now Alternative 2015 6.00 6.00 7.25 5.00 36.00 0.76
38 RL Porter Robinson Worlds Electronic 2014 7.17 7.25 7.75 6.50 43.00 0.47
37 SF Suburban Legends Dance Like Nobody's Watching Pop Rock 2006 5.79 5.88 6.75 5.00 34.75 0.70
36 MJ House of Protection GALORE Rock 2024 7.08 7.12 7.75 6.50 42.50 0.52
35 RW Dolly Parton Jolene Country 1974 6.75 6.88 7.25 5.75 40.50 0.52
34 JP The Backseat Lovers Elevator Days Rock 2018 6.32 6.25 6.75 6.00 44.25 0.24
33 TL Funeral for a Friend Seven Ways to Scream Your Name Post-hardcore 2003 6.83 6.75 7.75 6.00 41.00 0.61
32 RS Fightstar They Liked You Better When You Were Dead Rock 2005 6.41 6.38 7.25 5.75 51.25 0.52
31 MT Parcels Hideout Pop 2017 6.17 6.25 6.50 5.75 37.00 0.34
30 WS Devil Sold His Soul Belong ╪ Betray Metalcore 2014 7.00 6.88 8.00 6.25 42.00 0.74
29 RL Bad Rabbits Stick Up Kids Pop 2009 6.12 6.12 6.75 5.50 36.75 0.61
28 SF Foo Fighters Foo Fighters Rock 1995 6.14 6.00 7.50 4.50 43.00 0.99
27 RS Alien Ant Farm truANT Rock 2003 5.97 6.00 7.00 4.50 47.75 0.76
26 MJ Talking Heads Remain in Light New Wave 1980 6.79 7.00 7.50 6.00 47.50 0.55
25 RW Griff Vertigo Pop 2024 6.39 6.50 7.50 5.50 44.75 0.61
24 JP Childish Gambino Bando Stone & The New World Hip Hop 2024 6.43 6.25 7.75 4.50 45.00 1.13
23 TL Chicane Giants Dance 2010 6.61 6.50 8.00 5.50 46.25 1.02
22 MT Tom Misch Geography Alternative 2018 6.57 6.75 7.25 6.00 46.00 0.45
21 WS Sleep Token Take Me Back to Eden Metal 2023 5.58 5.38 7.00 4.50 33.50 0.85
20 RL Joe Satriani Surfing with the Alien Rock 1987 5.64 5.50 7.00 5.00 39.50 0.70
19 RS The Wildhearts Earth vs the Wildhearts Rock 1993 5.12 5.12 6.25 4.00 41.00 0.96
18 RS Beartooth The Surface Metalcore 2023 7.28 7.50 8.00 6.50 58.25 0.49
17 SF As December Falls As December Falls Rock 2019 5.75 6.00 6.50 3.75 40.25 0.91
16 MJ MisterWives Our Own House Pop Rock 2015 7.00 6.75 8.25 5.75 49.00 0.94
15 RW Live Throwing Copper Rock 1994 5.71 5.75 6.50 4.75 40.00 0.64
14 JP Post Malone Hollywood's Bleeding Hip Hop 2019 5.11 5.25 6.00 4.25 35.75 0.64
13 TL Grimes Art Angels Pop 2015 6.79 7.25 8.50 4.75 47.50 1.26
12 MT IDLES Joy as an Act of Resistance Punk 2018 6.36 6.50 7.00 5.25 44.50 0.63
11 WS Every Time I Die Radical Metalcore 2021 6.11 6.50 7.50 3.00 42.75 1.48
10 RL Sigur Rós ( ) Post Rock 2002 5.71 5.75 7.50 3.00 40.00 1.42
9 SF Newton Faulkner Hand Built by Robots Pop Rock 2007 5.07 5.50 6.50 3.50 35.50 1.16
8 RS Linkin Park The Hunting Party Rock 2014 5.53 6.50 6.75 3.00 44.25 1.67
7 MJ Electric Six Fire Rock 2003 6.93 7.00 8.50 4.75 48.50 1.17
6 RW Tracy Chapman Tracy Chapman Roots Rock 1988 7.50 7.50 8.00 7.25 52.50 0.25
5 JP Kendrick Lamar Mr. Morale & the Big Steppers Hip Hop 2022 5.50 5.00 7.00 4.25 38.50 1.08
4 TL Talk Talk The Colour of Spring New Wave 1986 6.54 6.75 7.25 5.50 45.75 0.60
3 MT Jungle Volcano Electronic 2023 6.43 6.00 8.00 5.75 45.00 0.86
2 WS The Black Queen Fever Daydream Electronic 2016 5.07 5.25 6.75 3.00 35.50 1.22
1 RL M83 Before the Dawn Heals Us Electronic 2005 5.81 6.00 6.50 5.00 46.50 0.55

Aggregations

Average Scores by Advocate

advocates_counts = master.groupby('From')['#'].agg('count').reset_index()
advocates_averages = pd.pivot_table(master, values=['AVG','MAX','MED','MIN','SUM'], index="From",columns=None).reset_index()
advocates_combined = pd.merge(advocates_counts,advocates_averages,how="inner").rename(columns={'#':'Albums'})

show(advocates_combined.style
                       .background_gradient(subset=['AVG','MAX','MIN'], cmap='Blues') \
                       .format(precision=2))
From Albums AVG MAX MED MIN SUM
JP 8 6.04 7.03 5.92 5.06 38.31
MJ 7 6.79 7.68 6.84 5.75 40.89
MT 8 6.38 7.09 6.39 5.69 40.66
RL 8 6.20 7.00 6.25 5.25 38.56
RS 5 6.06 7.05 6.30 4.75 48.50
RW 7 6.71 7.46 6.80 5.86 41.14
SF 7 6.14 7.00 6.31 4.86 39.25
TL 8 6.92 8.16 6.98 5.62 42.28
WS 8 5.94 7.12 5.97 4.66 35.66

Average Scores by Decade

album_counts_by_decade = master.groupby('Decade',observed=True)['#'].agg('count').reset_index()
scores_by_decade = master.groupby(['Decade'], observed=True)[players+aggs].agg('mean').fillna('').reset_index()
combined_by_decade = pd.merge(album_counts_by_decade,scores_by_decade,how="inner").rename(columns={'Year':'Decade','#':'Albums'})

show(combined_by_decade.style \
                       .background_gradient(subset=['Albums','AVG','MAX','MIN'], cmap='Greens') \
                       .format(precision=2))
Decade Albums JP MJ MT RL RS RW SF TL WS AVG MED MAX MIN SUM STD
1970s 4 6.88 6.88 5.58 7.00 7.00 7.00 6.94 6.94 6.75 6.91 7.25 5.94 37.12 0.55
1980s 5 6.45 6.94 6.85 7.00 6.25 6.62 6.58 6.80 6.70 6.85 7.50 5.85 44.10 0.61
1990s 6 5.88 6.80 6.08 5.55 5.56 6.25 6.12 5.33 5.98 6.04 6.83 4.83 37.54 0.77
2000s 17 6.17 6.47 6.10 6.85 5.00 6.41 6.88 6.09 6.32 6.40 6.37 7.40 5.38 40.49 0.73
2010s 23 5.90 6.59 5.57 6.58 6.40 6.12 6.31 6.42 6.28 6.41 7.23 5.15 39.47 0.80
2020s 11 6.85 6.72 6.09 5.86 6.35 6.08 6.57 6.72 6.36 6.32 7.45 5.20 42.27 0.79

Average Proximities

dists_from_avg = pd.merge(left=scores_aggs.iloc[:,:2],right=scores_players,how='inner')
for player in order:
    dists_from_avg[player] = dists_from_avg[player] - dists_from_avg['AVG']

avg_calcs = []
for player in order:
    avg_calcs.append([player,len(dists_from_avg.query(f'{player} > 0')),len(dists_from_avg.query(f'{player} == 0')),len(dists_from_avg.query(f'{player} < 0'))])
avg_calcs = pd.DataFrame(avg_calcs,columns=["Player","Above Average","Exactly Average","Below Average"])

melt_for_avg_calcs = dists_from_avg.melt(id_vars=['#'],value_vars=players,var_name='Judge', value_name='Score')
melt_for_avg_calcs['Score'] = melt_for_avg_calcs['Score'].abs()

closest_to_avg_counts = []
for player in players:
    count = 0
    for album_num in range(1,album_count+1):
        album_scores = melt_for_avg_calcs[melt_for_avg_calcs['#'] == album_num]
        min_scores = album_scores[album_scores.Score == album_scores.Score.min()]
        try:
            count += min_scores['Judge'].value_counts()[player]
        except:
            pass
    closest_to_avg_counts.append((player,str(count)))
    
closest_to_avg_counts = pd.DataFrame(closest_to_avg_counts,columns=["Player","Closest to Average"])
combined_avg_calcs = pd.merge(avg_calcs,closest_to_avg_counts,how="inner").sort_values('Player').set_index("Player").reset_index()
combined_avg_calcs = combined_avg_calcs.iloc[:,:].style \
                     .background_gradient(subset=["Above Average","Exactly Average","Below Average","Closest to Average"],cmap='Blues') \
                     .format(precision=2)

show(combined_avg_calcs)
Player Above Average Exactly Average Below Average Closest to Average
JP 15 2 15 12
MJ 42 3 14 16
MT 19 1 38 10
RL 28 2 18 11
RS 0 0 1 0
RW 25 1 33 17
SF 25 2 19 10
TL 29 3 26 15
WS 31 3 24 19

Relationship Matrix

relationship_matrix = pd.merge(left=albums.iloc[:,:4],right=scores_players,how='inner')
columns = ["Judge"] + players

matrix_list = []
for judge in players:
    avg_for_each_player = [judge]   
    for advocate in players:
        submatrix = relationship_matrix[relationship_matrix["From"] == advocate]
        avg_for_each_player.append(submatrix[judge].mean())
    matrix_list.append(avg_for_each_player)
    
relationship_matrix = pd.DataFrame(matrix_list,columns=columns).set_index("Judge").reset_index().style \
                     .background_gradient(cmap='Greens') \
                     .format(precision=2)
show(relationship_matrix.map(lambda x: 'color: transparent; background-color: transparent' if pd.isnull(x) else ''))
Judge JP MJ MT RL RS RW SF TL WS
JP nan 6.75 7.10 5.58 6.25 6.38 6.06 6.31 5.25
MJ 6.59 nan 6.47 6.22 6.70 6.89 6.71 6.84 6.75
MT 5.84 7.00 nan 5.78 5.60 6.29 5.25 6.06 5.81
RL 5.67 6.75 6.21 nan 6.30 6.75 6.46 7.79 5.29
RS nan nan nan 5.00 nan nan nan nan nan
RW 6.06 6.89 6.19 6.34 6.20 nan 6.39 6.97 5.75
SF 5.50 6.50 6.25 6.42 6.50 6.80 nan 6.71 6.17
TL 6.28 6.68 6.19 6.53 5.95 7.00 5.93 nan 6.12
WS 5.84 7.00 6.47 6.16 5.00 6.68 5.96 7.53 nan

Advocates' Eras

advocates_eras = albums.groupby('From',observed=True)['Year'].agg(['mean','median','max','min']) 
advocates_eras = advocates_eras.rename(columns={'mean':'AVG','median':'MED','max':'MAX','min':'MIN'}).reset_index()
show(advocates_eras.style \
                       .background_gradient(subset='AVG',cmap='Blues') \
                       .format(precision=0,subset=['AVG','MED']))
From AVG MED MAX MIN
JP 2015 2017 2024 2001
MJ 2006 2010 2024 1980
MT 2014 2018 2025 1977
RL 2006 2006 2016 1987
RS 2008 2005 2023 1993
RW 1991 1991 2024 1965
SF 2000 2001 2019 1971
TL 2003 2004 2018 1986
WS 2018 2016 2023 2014

Advocates' Genres

advocates_genres = pd.pivot_table(albums, values='#', index='Genre',columns='From', aggfunc="count")
advocates_genres['Total'] = advocates_genres.sum(axis=1)
advocates_genres = advocates_genres.sort_values(by='Total',ascending=False).reset_index()
advocates_genres = advocates_genres.style \
                         .background_gradient(cmap='Blues')

show(advocates_genres.map(lambda x: 'color: transparent; background-color: transparent' if x == 0 else ''))
Genre JP MJ MT RL RS RW SF TL WS Total
Rock 2 2 0 1 4 2 3 0 0 14
Electronic 0 1 2 2 0 0 0 0 1 6
R&B 1 0 0 1 0 0 0 1 2 5
Pop 0 0 1 2 0 1 0 1 0 5
Hip Hop 4 1 0 0 0 0 0 0 0 5
Pop Rock 0 1 0 0 0 0 2 1 0 4
Metalcore 0 0 0 0 1 0 0 0 3 4
New Wave 0 1 0 0 0 0 0 2 0 3
Alternative 0 0 1 0 0 0 0 0 1 2
Jazz 0 0 1 0 0 1 0 0 0 2
Metal 0 0 0 0 0 0 0 1 1 2
Indie Rock 1 0 1 0 0 0 0 0 0 2
Dance 0 0 0 1 0 0 0 1 0 2
Indietronica 0 1 0 0 0 0 0 0 0 1
Country 0 0 0 0 0 1 0 0 0 1
Folk Rock 0 0 0 0 0 1 0 0 0 1
Dubstep 0 0 1 0 0 0 0 0 0 1
Pop Punk 0 0 0 0 0 0 1 0 0 1
Digital Hardcore 0 0 0 0 0 0 1 0 0 1
Post Rock 0 0 0 1 0 0 0 0 0 1
Post-hardcore 0 0 0 0 0 0 0 1 0 1
Punk 0 0 1 0 0 0 0 0 0 1
Country Pop 0 0 0 0 0 1 0 0 0 1
Roots Rock 0 0 0 0 0 1 0 0 0 1

Scores by Round

Aggs

scores_by_round = master.groupby(['Round'], observed=True)[aggs].agg(['mean','max','min']).fillna('').reset_index()

show(scores_by_round.style \
                       .background_gradient(subset=aggs,cmap='Greens') \
                       .format(precision=2),classes="compact")
Round AVG MED MAX MIN SUM STD
mean max min mean max min mean max min mean max min mean max min mean max min
1 6.04 7.50 5.07 6.17 7.50 5.00 7.25 8.50 6.50 4.67 7.25 3.00 43.56 52.50 35.50 0.95 1.67 0.25
2 6.09 7.28 5.11 6.24 7.50 5.12 7.20 8.50 6.00 4.50 6.50 3.00 43.90 58.25 35.75 0.94 1.48 0.49
3 6.24 6.79 5.58 6.21 7.00 5.38 7.39 8.00 7.00 5.11 6.00 4.50 43.69 47.75 33.50 0.78 1.13 0.45
4 6.50 7.08 5.79 6.50 7.12 5.88 7.19 8.00 6.50 5.83 6.50 5.00 41.11 51.25 34.75 0.53 0.74 0.24
5 6.68 7.67 5.88 6.72 7.50 5.88 7.56 9.00 6.50 5.81 7.50 4.50 40.84 46.00 35.25 0.71 1.16 0.26
6 6.57 7.38 5.71 6.63 7.25 5.88 7.34 9.00 6.75 5.53 6.50 4.00 38.53 44.25 34.25 0.68 1.07 0.29
7 6.45 7.05 5.90 6.53 7.50 6.00 7.19 7.75 6.25 5.62 6.50 5.00 32.31 41.25 24.75 0.66 1.05 0.29
8 6.42 7.00 5.25 6.40 7.00 5.00 7.25 8.00 6.75 5.60 7.00 4.25 33.50 42.00 26.25 0.64 1.02 0.00

Players

scores_by_round = master.groupby(['Round'], observed=True)[players[:4]].agg(['mean','max','min']).reset_index()

scores_by_round = scores_by_round.style \
                       .background_gradient(subset=players[:4],cmap='Blues') \
                       .format(precision=2)
ignore = ['Round']
show(scores_by_round.map(lambda x: 'color: transparent; background-color: transparent' if pd.isnull(x) else ''),classes="compact")
Round JP MJ MT RL
mean max min mean max min mean max min mean max min
1 6.25 8.00 4.75 6.56 7.50 6.00 5.16 8.50 3.00 6.06 7.50 4.25
2 6.19 7.00 5.50 6.53 7.50 5.75 5.28 6.75 3.00 5.94 8.50 3.00
3 6.46 7.00 5.50 6.59 7.50 6.00 5.97 7.00 4.50 6.25 8.00 4.50
4 7.00 7.00 7.00 6.50 6.75 6.00 6.12 7.75 5.00 6.66 7.75 6.00
5 nan nan nan 6.96 7.50 6.50 6.21 7.75 4.50 6.93 9.00 5.00
6 5.75 5.75 5.75 6.71 7.25 6.00 6.86 8.00 6.00 6.54 8.00 4.00
7 6.00 6.75 5.00 6.71 7.75 5.75 6.25 7.50 5.25 7.75 7.75 7.75
8 6.00 7.00 5.00 6.60 7.00 5.75 6.25 7.50 5.00 nan nan nan
scores_by_round = master.groupby(['Round'], observed=True)[players[5:]].agg(['mean','max','min']).reset_index()

scores_by_round = scores_by_round.style \
                       .background_gradient(subset=players[5:],cmap='Blues') \
                       .format(precision=2)

show(scores_by_round.map(lambda x: 'color: transparent; background-color: transparent' if pd.isnull(x) else ''),classes="compact")
Round RW SF TL WS
mean max min mean max min mean max min mean max min
1 6.16 7.75 4.75 6.22 7.25 4.25 6.03 7.25 3.75 5.94 7.50 3.00
2 6.31 8.00 4.50 6.17 7.50 4.75 6.25 7.50 4.00 6.11 7.50 4.00
3 5.97 6.50 5.25 6.00 6.75 5.25 6.22 7.75 4.50 6.50 7.75 4.50
4 6.50 7.50 5.75 6.81 7.25 6.25 6.31 8.00 5.00 6.47 7.75 5.50
5 6.79 7.50 5.50 6.39 8.25 5.25 6.68 7.50 5.25 6.71 8.00 4.50
6 6.14 6.75 5.75 6.62 7.50 5.50 6.71 7.25 5.50 6.46 9.00 4.00
7 6.46 7.75 5.50 nan nan nan 6.43 7.75 5.75 6.54 7.50 5.50
8 6.60 8.00 4.50 6.88 7.00 6.75 6.12 7.00 4.25 6.56 7.00 6.00

Visualisations

melted = master.melt(id_vars=['#','From','Artist','Album'],value_vars=players,var_name='Judge', value_name='Score')

params = {"AVG" : ["mean",melted.groupby(["Judge"])["Score"].mean()],
          "MED" : ["median",melted.groupby(["Judge"])["Score"].median()],
          "SUM" : ["sum",melted.groupby(["Judge"])["Score"].sum()],
          "MAX" : ["max",melted.groupby(["Judge"])["Score"].max()],
          "MIN" : ["min",melted.groupby(["Judge"])["Score"].min()],
          "STD" : ["std",melted.groupby(["Judge"])["Score"].std()]}

Scores by Judge

plt.figure(figsize=(16,8))
for i, agg in enumerate(aggs):
    plt.subplot(2,3,i+1)
    ax = sns.barplot(data=melted,x='Judge',y='Score',
                     estimator=params[agg][0],order=params[agg][1].sort_values(ascending=False).index,
                     alpha=0.65,errorbar=None)
    ax.margins(y=0.10)
    plt.title(agg),plt.xlabel(''),plt.ylabel('')
    for p in ax.patches:
        ax.annotate(format(p.get_height(), '.2f'), 
                   (p.get_x() + p.get_width() / 2., p.get_height()), 
                    ha = 'center', va = 'center', 
                    size=8,xytext = (0, 5), 
                    textcoords = 'offset points')
plt.subplots_adjust(left=0.1,bottom=0.1,right=1,top=0.75,wspace=0.1,hspace=0.3)
plt.show()

Score Distributions by Judge

plt.figure(figsize=(20,20))
for i, player in enumerate(players_trimmed):
    players_scores = melted[melted['Judge'] == player].groupby(by=["Score"], dropna=True).count().reset_index()
    plt.subplot(5,2,i+1)
    ax = sns.barplot(data=players_scores,x='Score',y='Judge',
                     alpha=0.65,errorbar=None)
    ax.margins(y=0.10)
    plt.title(player),plt.xlabel(''),plt.ylabel('')
    for p in ax.patches:
        ax.annotate(format(p.get_height(), '.0f'), 
                   (p.get_x() + p.get_width() / 2., p.get_height()), 
                    ha = 'center', va = 'center', 
                    size=10,xytext = (0, -10), 
                    textcoords = 'offset points')
plt.subplots_adjust(left=0.1,bottom=0.1,right=1,top=1,wspace=0.1,hspace=0.3)
plt.show()

Scores by Years and Mins

#plt.figure(figsize=(16,5))
#for i, param in enumerate(["Year","Mins"]):
#    plt.subplot(1,2,i+1)
#    sns.scatterplot(data=master,x='AVG',y=param,hue='From',s=200)
#    plt.xlabel(''),plt.ylabel(''),plt.title(f'{param} / Avg. Score'),plt.grid(True,axis="y")
#plt.subplots_adjust(left=0.1,bottom=0.1,right=1,top=0.75,wspace=0.1,hspace=0.3)
#plt.show()
for i, param in enumerate(["Year","Mins"]):
    fig = px.scatter(master, x=param, y="AVG", color="From",symbol="From",
    custom_data = ['From','Artist','Album'],title=f'{param} / Average Score',
                    category_orders={'From': players})
    fig.update_layout(autosize=True,height=500,title_x=0.5)
    fig.update_yaxes(title="Average Score")
    fig.update_traces(marker_size=15,
                      hovertemplate="<br>".join([
                                    "From: %{customdata[0]}",
                                    "Artist: %{customdata[1]}",
                                    "Album: %{customdata[2]}",
                                    f"{param}:" +" %{y}",
                                    "Average Score: %{x}"]))
    fig.show()

Scores by Album

#plt.figure(figsize=(16,4))
#ax = sns.lineplot(data=melted,x="#", y="Score",linewidth=2.5,marker='o',errorbar=('pi', 100))
#plt.xlabel(''),plt.ylabel(''),plt.grid(True),plt.title('Average Score / Album')
#plt.show()
average_score_by_album = melted.groupby(['#','Album'])['Score'].mean().reset_index()
fig = px.line(average_score_by_album, x="#", y="Score",
              title='Average Score / Album',markers=True,
              custom_data = ['Album'])     
fig.update_layout(autosize=True,height=500,title_x=0.5)
fig.update_xaxes(title="Album")
fig.update_traces(line=dict(color="Green", width=2.5),
                            hovertemplate="<br>".join([
                                          "Album: %{customdata[0]}",
                                          "Average Score: %{y:,.2f}"]))
fig.show()
#plt.figure(figsize=(16,5))
#sns.lineplot(data=melted,x="#", y="Score", hue='Judge',linewidth=1.5,marker='o')
#plt.xlabel(''),plt.ylabel(''),plt.grid(True),plt.title('Judge\'s Scores / Album')
#plt.show()
fig = px.line(melted, x="#", y="Score",color='Judge',symbol='Judge',
              title='Judge\'s Scores / Album',markers=True,
              custom_data = ['Judge','Artist','Album'])
fig.update_layout(autosize=True,height=500,title_x=0.5)
fig.update_xaxes(title="Album")
fig.update_traces(connectgaps=True,
                  hovertemplate="<br>".join([
                                "Judge: %{customdata[0]}",
                                "Artist: %{customdata[1]}",
                                "Album: %{customdata[2]}",
                                "Score: %{y}"]))
fig.show()
#plt.figure(figsize=(20,20))
#for i, player in enumerate(players_trimmed):
#    players_scores = melted[melted['Judge'] == player]
#    plt.subplot(5,2,i+1)
#    ax = sns.lineplot(data=players_scores,x='#',y='Score',linewidth=3,marker='o',
#                     alpha=0.65,errorbar=None)
#    ax.margins(y=0.10)
#    plt.title(player),plt.xlabel(''),plt.ylabel(''),plt.grid(True)
#plt.subplots_adjust(left=0.1,bottom=0.1,right=1,top=1,wspace=0.1,hspace=0.3)
#plt.show()

Scores by Genre

plt.figure(figsize=(28,3))
ax = sns.barplot(data=master,x="Genre", y="AVG",alpha=0.65,errorbar=None)
for p in ax.patches:
    ax.annotate(format(p.get_height(), '.2f'), 
               (p.get_x() + p.get_width() / 2., p.get_height()), 
                ha = 'center', va = 'center', 
                size=10,xytext = (0, -10), 
                textcoords = 'offset points')
plt.xlabel(''),plt.ylabel('')
plt.show()

Scores by Categories

plt.figure(figsize=(16,8))
for i, cat in enumerate(["Origin","Gender","Group","POC"]):
    plt.subplot(2,2,i+1)
    ax = sns.barplot(data=master,x=cat, y="AVG",alpha=0.65,errorbar=None)
    plt.title("Score / " + cat),plt.xlabel(''),plt.ylabel('')
    for p in ax.patches:
        ax.annotate(format(p.get_height(), '.2f'), 
                   (p.get_x() + p.get_width() / 2., p.get_height()), 
                    ha = 'center', va = 'center', 
                    size=10,xytext = (0, -10), 
                    textcoords = 'offset points')   
plt.subplots_adjust(left=0.1,bottom=0.1,right=1,top=0.75,wspace=0.1,hspace=0.3)
plt.show()