Fantasy Wrap-up for 2016 D-I College Nationals

We'll scrape data from the USAU website to find the winner of /r/ultimate's fantasy lineup contest, and along the way find which players made the biggest score contributions at nationals, and how that correlated with users' fantasy valuations.

All of the following is being run in a jupyter notebook, which anyone can modify and run after installing python and a few other dependencies. Further instructions can be found in the github README.

We first set up some simple imports and display settings.


In [1]:
import usau.reports
import usau.fantasy

In [2]:
from IPython.display import display, HTML
import pandas as pd
pd.options.display.width = 200
pd.options.display.max_colwidth = 200
pd.options.display.max_columns = 200

%matplotlib inline
import matplotlib.pyplot as plt
import seaborn as sns

First we'll need to scrape data from the USAU website. I've also downloaded the data offline in the form of csvs, and the following cell instructs to load the data from these csvs instead of scraping the website on-the-fly. (A wrapper script for downloading the data can be found in usau/download_reports.py.) Stat-keeping seemed to be done pretty comprehensively this tournament, with only a couple of women's consolation games missing player statistics. Unlikely last year's tournament, stat-keepers also seemed to have done a good job recording players' Ds and turnovers.


In [3]:
# Read data from csv files
usau.reports.d1_college_nats_men_2016.load_from_csvs()
usau.reports.d1_college_nats_women_2016.load_from_csvs()
None  # No output

Let's also retrieve the fantasy picks from the /r/ultimate fantasy competition:


In [4]:
mens_fantasy, womens_fantasy, contest_users = usau.fantasy.compute_fantasy_picks()
display_cols = ["No.", "Name", "Fantasy Score", "Position", "Height",
                "Goals", "Assists", "Ds", "Turns",
                "Team", "Seed", "Fantasy Picks"]

And without further ado, the winner of the fantasy competition is /u/ultimatefrisbee, with /u/scottyskin96 and /u/duthracht respectively scoring the highest in the Men's and Women's competitions.


In [5]:
usau.fantasy.compute_fantasy_contest_results(display=False).reset_index(drop=True).style \
  .bar(subset=["Total", "Women's"],
       color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=["Men's"],
       color='rgba(200, 80, 80, 0.5)')


/apps/stonefs1/azhu/libs/usau_fantasy/usau/fantasy.py:81: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
  .sort(["Fantasy Score", "Seed"], ascending=False))
/apps/stonefs1/azhu/libs/usau_fantasy/usau/fantasy.py:116: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)
  results = results.sort("Total", ascending=False)[["User", "Total", "Men's", "Women's"]]
Out[5]:
User Total Men's Women's
0 ultimatefrisbee 462.4 252.6 209.8
1 scottyskin96 456.6 260.2 196.4
2 grhgra002 442.6 233.6 209
3 krdonnie 438 256 182
4 chubs45 430.4 218 212.4
5 samth 422.6 219.4 203.2
6 giftedbadly 418.6 208.2 210.4
7 dlquinonesII 417.8 228 189.8
8 duthracht 417.6 199.2 218.4
9 Ultimatezach 416.2 228.8 187.4
10 almondchipcookies 405.8 223.4 182.4
11 azjps 393.8 186 207.8
12 anti_spiral 373.8 187.4 186.4
13 livetweetyourgames 355.2 150.6 204.6

A look at the player statistics

Here are all players picked in fantasy, mixed with the other top fantasy point scoring athletes. "Fantasy point score" here is arbitrarily defined by the formula $G + A + 0.2 \times D - 0.2 \times T$. Ds and turns were weighted lightly mostly because I was worried that they might not be kept very accurately, but it seems the stat-keepers did a good job following these. Please note that as these statistics are for fantasy, where one of the objectives was to predict which teams would go deepest, none of the statistics in this notebook are normalized for games played, points played, and so forth. Such might be a good subject for another notebook though, wink wink.


In [6]:
usau.fantasy.compute_athlete_fantasy_scores(mens_fantasy, min_players=25)[display_cols].style \
  .bar(subset=['Fantasy Score', 'Goals', 'Ds', 'Fantasy Picks'],
             color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=['Assists', 'Turns'],
             color='rgba(200, 80, 80, 0.5)')


Out[6]:
No. Name Fantasy Score Position Height Goals Assists Ds Turns Team Seed Fantasy Picks
289 14 John Stubbs 49.8 nan 6'0" 26 26 5 16 Harvard 10 13
399 1 Ryan Osgar 39.8 Deep 6'1" 14 27 5 11 Minnesota 4 2
402 4 Ben Jagt 39.2 Defense (Cutter) 6'4" 23 17 6 10 Minnesota 4 11
294 23 Mark Vandenberg 38.6 Handler 6'1" 10 30 10 17 Harvard 10 5
64 3 Khalif El-Salaam 33.6 Defense (Cutter) nan 15 19 5 7 Washington 13 7
385 16 Trent Dillon 33.6 Defense (Cutter/Handler) 5'11" 15 20 5 12 Pittsburgh 5 5
376 3 Patrick Earles 31 Handler/Cutter 6'2" 9 23 1 6 Pittsburgh 5 4
153 0 Aaron Warshauer 31 Deep 6'3" 23 8 9 9 North Carolina 7 0
113 8 Pawel Janas 29.6 Handler 5'10" 15 16 1 8 Colorado 11 0
20 88 Nathan Haskell 26.4 nan nan 8 19 6 9 Georgia 8 0
179 2 Robert Patterson 25.8 nan nan 4 24 2 13 Florida State 14 0
295 24 David Reshef 25.4 Cutter 5'9" 19 7 1 4 Harvard 10 0
215 23 Tarik Akyuz 25.2 nan nan 16 10 6 10 Case Western Reserve 18 0
170 23 Walker Matthews 24.8 nan nan 12 14 5 11 North Carolina 7 0
42 87 Jeffrey Babbitt 24.6 Deep 6'2" 18 7 2 4 Massachusetts 1 9
169 21 Matt Gouchoe-Hanas 23.8 nan nan 9 16 3 9 North Carolina 7 0
419 48 Wyatt Mekler 23.6 Handler 1'0" 13 12 4 11 Minnesota 4 0
139 23 Xander Cuizon Tice 23.4 nan nan 20 3 4 2 Oregon 2 0
49 13 Dalton Smith 22.8 Defense (Handler) 5'10" 6 20 6 22 Texas A&M 12 18
320 31 John Wodatch 22.4 Deep 6'1" 8 16 3 11 Connecticut 19 0
89 9 Nathan Pettyjohn 21.8 Handler nan 16 7 3 9 Cal Poly-SLO 17 0
243 25 Ross Barker 21.6 Deep 5'11" 15 7 3 5 Wisconsin 6 0
21 3 Ben Sadok 21.4 Deep 5'5" 10 13 3 11 Massachusetts 1 1
371 83 Ryan Landry 21 nan nan 9 13 2 7 Auburn 16 1
163 12 Elijah Long 20.8 nan 5'11" 10 11 5 6 North Carolina 7 0
380 10 Max Thorne 19.6 Mid 5'7" 13 8 2 9 Pittsburgh 5 2
196 27 Connor Holcombe 18 nan nan 11 8 0 5 Florida State 14 2
5 9 Samuel Little 18 nan nan 8 12 2 12 Georgia 8 1
140 24 Adam Rees 18 nan nan 3 15 4 4 Oregon 2 1
206 3 Joseph Marmerstein 17.4 nan 1'0" 2 18 4 17 Case Western Reserve 18 1
240 22 Aaron Speiss 15.2 Deep 5'10" 8 7 2 1 Wisconsin 6 1
346 80 Xavier Maxstadt 14 nan nan 1 14 5 10 North Carolina-Wilmington 3 8
28 15 Tannor Johnson 13 Deep 6'3" 7 8 1 11 Massachusetts 1 5
146 55 Connor Matthews 12.8 nan 6'0" 5 9 0 6 Oregon 2 5
26 11 Conor Kline 12.2 Deep nan 8 4 3 2 Massachusetts 1 5
339 23 Jack Williams 10.6 nan nan 5 6 3 5 North Carolina-Wilmington 3 5

At a glance, its clear the dynamic duos of the two teams which made it the deepest, Stubbs and Vandenberg of Harvard and Osgar and Jagt of Minnesota, racked up the most impressive stat lines of the tournaments. Osgar in particular managed this despite sitting out the Minnesota's semifinal win with a knee injury, and playing through the same injury in the finals.


In [7]:
usau.fantasy.compute_athlete_fantasy_scores(womens_fantasy, min_players=25)[display_cols].style \
  .bar(subset=['Fantasy Score', 'Goals', 'Ds', 'Fantasy Picks'],
             color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=['Assists', 'Turns'],
             color='rgba(200, 80, 80, 0.5)')


Out[7]:
No. Name Fantasy Score Position Height Goals Assists Ds Turns Team Seed Fantasy Picks
134 8 Angela Zhu 39.6 nan 1'0" 7 38 9 36 Dartmouth 18 4
140 21 Jaclyn Verzuh 36 Defense (Cutter) 6'0" 18 20 6 16 Dartmouth 18 3
24 2 Jesse Shofner 33 nan nan 7 27 6 11 Oregon 1 21
228 23 Courtney Gegg 31.8 Cutter 6'0" 22 12 0 11 Stanford 3 5
30 9 Olivia Bartruff 29.4 nan nan 25 4 5 3 Oregon 1 3
20 44 Keila Strick 29 nan nan 19 11 3 8 Virginia 13 0
386 11 Janina Freystaetter 27.2 Defense (Cutter) 5'9" 10 16 24 18 Central Florida 4 9
325 15 Alex Hardesty 27 nan nan 9 22 9 29 Whitman 5 0
124 25 Han Chen 26.8 Handler/Cutter 1'0" 8 22 11 27 UCLA 7 7
157 19 Mira Donaldson 26.2 Cutter nan 1 29 8 27 British Columbia 2 15
213 44 Abbie Abramovich 25.6 nan nan 17 10 3 10 Chaos (Independent) 14 1
332 28 Claire Revere 25.6 nan 5'5" 5 20 11 8 Whitman 5 5
94 17 Patricia Weicht 24 nan nan 22 4 4 14 Colorado College 17 0
28 7 Alexandra Ode 24 nan 5'8" 13 10 10 5 Oregon 1 0
45 4 Nhi Nguyen 21.8 nan 5'5" 16 7 5 11 Colorado 8 0
323 11 Marlena Sloss 21.8 nan nan 21 1 5 6 Whitman 5 0
361 4 Lorraine Guerin 21.8 nan 5'8" 14 6 17 8 Wisconsin 16 0
40 27 Hayley Wahlroos 21.8 nan nan 11 12 6 12 Oregon 1 3
167 47 Victoria Mccann 21.6 Cutter nan 13 9 5 7 British Columbia 2 0
318 4 Nina Finley 21.6 Mid 5'6" 7 17 11 23 Whitman 5 0
150 8 Kate Scarth 21.4 nan 1'0" 15 7 3 6 British Columbia 2 4
232 60 Caitlin Go 20.6 Handler nan 9 11 7 4 Stanford 3 0
368 14 Anna Hrovat-Staedter 20.2 nan 5'6" 1 20 8 12 Wisconsin 16 0
110 4 Kristen Pojunis 20.2 Handler/Cutter 5'7" 17 6 2 16 UCLA 7 5
144 55 Julianna Werffeli 18.6 nan nan 9 10 10 12 Dartmouth 18 0
86 6 Chloe Rowse 17.8 nan nan 8 11 4 10 Colorado College 17 1
49 9 Kirstin Johnson 17.8 nan 5'4" 2 17 7 13 Colorado 8 2
31 11 Bethany Kaylor 17.6 nan 1'0" 3 16 7 14 Oregon 1 7
391 66 Stephanie Williams 13.6 nan 3'8" 0 18 1 23 Central Florida 4 1
224 14 Monisha White 13.2 Handler nan 1 13 12 16 Stanford 3 2
65 2 Marisa Rafter 12.4 nan nan 4 9 4 7 California 12 6
382 6 Alexa Wood 10.2 nan nan 9 1 7 6 Central Florida 4 1
189 36 Carolyn Normile 9.6 Handler 5'3" 3 9 8 20 Pittsburgh 11 2
384 8 Shayna Brock 8.4 nan nan 4 8 7 25 Central Florida 4 5

It is perhaps surprising then that the top women's stat lines belonged to the Dartmouth duo Angela Zhu and Jaclyn Verzuh, as Dartmouth exited the tournament in the quarterfinals, playing 1 fewer games than the finalists Stanford and Whitman (not 2, as /u/samth points out). This is not to take away anything from Gegg/White and Hardesty/Revere, who anchored the deeper lines of their respective teams and put in respectable stats too.

Let's get a graphical sense of the highest performers, as far as stat lines went:


In [8]:
# Clean up the data a little bit
mens_fantasy_clean = usau.fantasy.compute_athlete_fantasy_scores(mens_fantasy, min_players=len(mens_fantasy))[display_cols]
womens_fantasy_clean = usau.fantasy.compute_athlete_fantasy_scores(womens_fantasy, min_players=len(womens_fantasy))[display_cols]
mens_fantasy_clean["Gender"] = "Men"
womens_fantasy_clean["Gender"] = "Women"
fantasy_clean = pd.concat([mens_fantasy_clean, womens_fantasy_clean]).sort(columns=["Fantasy Score"], ascending=False)
# Plotting styles
style_args = {"alpha": 0.5, "markeredgewidth": 0.5}
sns_blue, sns_green, sns_red, sns_magenta, sns_yellow, sns_cyan = sns.color_palette()


/spare/local/azhu/venv_el6-usau-stonelib/lib/python2.7/site-packages/ipykernel/__main__.py:6: FutureWarning: sort(columns=....) is deprecated, use sort_values(by=.....)

In [9]:
# Plot goals versus assists, labelling the top 20 performers of both genders
fig, ax = plt.subplots(figsize=(18, 11))
ax.plot(mens_fantasy_clean.Goals, mens_fantasy_clean.Assists, "o", color=sns_blue, **style_args)
ax.plot(womens_fantasy_clean.Goals, womens_fantasy_clean.Assists, "o", color=sns_red, **style_args)
ax.set_xlabel("Goals")
ax.set_ylabel("Assists")
ax.set_title("Goals versus Assists")
for _, row in mens_fantasy_clean.head(20).iterrows():
  adjustment = 0.2
  ax.annotate(row["Name"], xy=(row["Goals"] + adjustment, row["Assists"] + adjustment),
              ha='left', va='center', rotation=30, wrap=True, color=sns_blue)
for _, row in womens_fantasy_clean.head(20).iterrows():
  adjustment = 0.2
  ax.annotate(row["Name"], xy=(row["Goals"] + adjustment, row["Assists"] + adjustment),
              ha='left', va='center', rotation=30, wrap=True, color=sns_red)


John Stubb's contributions across the tournament can't be understated; he excelled on both sides of the disc, catching the most goals across both genders while also having the sixth highest assist count (behind only Osgar and teammate Vandenberg on the men's side). Angela Zhu also impressively notched over 25% more assists than anyone else in the tournament.

Who were the most efficient players, with lots of contributions but few turnovers?


In [10]:
# Plot As versus turns, labelling the top values of both genders
# Using the top 500 players by fantasy (at least 2 scores/assists) to prune some of the null data
g = sns.lmplot("Assists", "Turns", fantasy_clean.head(500), hue="Gender",
               size=12, palette={"Men": sns_blue, "Women": sns_red})
g.ax.set_title(u"Offensive Throwing Efficiency, ▲ = more turnovers")
for _, row in mens_fantasy_clean[(mens_fantasy_clean.Assists > 18) |
                                 (mens_fantasy_clean.Turns > 18)].iterrows():
  adjustment = 0.3
  xy = (row["Assists"] + adjustment, row["Turns"] + 0.8)
  g.ax.annotate(row["Name"], xy=xy,
                ha='left', va='center', rotation=30, wrap=True, color=sns_blue)
for _, row in womens_fantasy_clean[(womens_fantasy_clean.Assists > 18) |
                                   (womens_fantasy_clean.Turns > 18)].iterrows():
  adj = 0.3
  x = row["Assists"]
  y = row["Turns"]
  # Couple of special cases for people whose names are obscured
  if row["Name"] == "Nina Finley":
    g.ax.annotate(row["Name"], xy=(x, y), xytext=(x + 1.0, y + 2.0),
                  arrowprops=dict(facecolor=sns_red, headwidth=6, headlength=8, width=2.0, alpha=0.3),
                  ha='left', va='center', rotation=30, wrap=True, color=sns_red)
  elif row["Name"] == "Stephanie Williams":
    g.ax.annotate(row["Name"], xy=(x, y), xytext=(x + 1.4, y),
                  arrowprops=dict(facecolor=sns_red, headwidth=6, headlength=8, width=2.0, alpha=0.3),
                  ha='left', va='center', rotation=30, wrap=True, color=sns_red)
  else:  
    g.ax.annotate(row["Name"], xy=(x + adj, y + adj - 0.4),
                  ha='left', va='center', rotation=30, wrap=True, color=sns_red)


Not surprisingly, the backfield players shouldering the responsibility for distributing the disc tended to have more turnovers. For the number of touches Angela Zhu had, her assist/turnover ratio was still quite respectable compared to other elite handlers (Hardesty, Lozano Chen). Jesse Shofner also was impressively consistent. On the men's side, Pat Earles stood out with the best assist/turnover ratio, despite having a reputation of being trigger-happy with the disc. For example, he threw more assists than Dalton Smith, with 3x fewer turnovers (although of course, some of this has to be attributed to Pittsburgh's offensive receivers' prowess). In general, the women's side tended to have a higher ratio of turnovers, which were probably exacerbated by the weather conditions on Sunday.

How about on defense?


In [11]:
# Plot goals+assists versus Ds, labelling the top 20 performers of both genders
fig, ax = plt.subplots(figsize=(18, 11))
ax.plot(mens_fantasy_clean.Goals + mens_fantasy_clean.Assists, mens_fantasy_clean.Ds, "o", color=sns_blue, **style_args)
ax.plot(womens_fantasy_clean.Goals + womens_fantasy_clean.Assists, womens_fantasy_clean.Ds, "o", color=sns_red, **style_args)
ax.set_xlabel("Goals + Assists")
ax.set_ylabel("Ds")
ax.set_title("Offensive versus Defensive work")
ax.set_ylim(0, 28)
for _, row in fantasy_clean[(fantasy_clean.Ds > 8) |
                            (fantasy_clean.Goals + fantasy_clean.Assists > 35)].iterrows():
  adjustment = 0.2
  x, y = row["Goals"] + row["Assists"], row["Ds"]
  color = sns_blue if row["Gender"] == "Men" else sns_red
  if row["Name"] == "Nicholas Ladas":
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 0.2, y + 0.6),
                ha='left', va='center', rotation=30, wrap=True, color=color)
  elif row["Name"] in ("Aaron Warshauer", "Martin Newman", "Alexandra Ode"):
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 0.4, y - 0.4),
                ha='left', va='center', rotation=30, wrap=True, color=color)
  else:
    ax.annotate(row["Name"], xy=(x + adjustment,y  + adjustment),
                ha='left', va='center', rotation=30, wrap=True, color=color)


It was hard to come by Ds on the men's side, but on the women's side, Janina Freystaetter really impressed on defense. She came up huge with 24 Ds, including 7 in their universe point loss to the finalists Whitman Sweets. She averaged 5.5 defensive blocks a game across UCF's four pool play games, and probably would have notched up a lot more if injuries and a short roster didn't bring UCF down.

Fantasy valuations

How good was /r/ultimate at predicting the best fantasy players? Not that bad, really.


In [12]:
# Plot goals versus assists, labelling the top 20 performers of both genders
fig, ax = plt.subplots(figsize=(18, 11))
mens_fantasy_pos = mens_fantasy_clean[mens_fantasy_clean["Fantasy Picks"] > 0]
womens_fantasy_pos = womens_fantasy_clean[womens_fantasy_clean["Fantasy Picks"] > 0]
ax.plot(mens_fantasy_pos["Fantasy Picks"], mens_fantasy_pos["Fantasy Score"], "o", color=sns_blue, **style_args)
ax.plot(womens_fantasy_pos["Fantasy Picks"], womens_fantasy_pos["Fantasy Score"], "o", color=sns_red, **style_args)

ax.set_xlabel("Fantasy Picks")
ax.set_ylabel("Fantasy Score = G + A + 0.2D - 0.2T")
ax.set_title("Fantasy Valuations")
ax.set_ylim(0, 55)
for _, row in fantasy_clean[(fantasy_clean["Fantasy Picks"] > 1) |
                            (fantasy_clean["Fantasy Score"] > 25)].iterrows():
  x = row["Fantasy Picks"]
  y = row["Fantasy Score"]
  adjustment = 0.2
  color = sns_blue if row["Gender"] == "Men" else sns_red
  # Couple of special cases for people whose names are obscured
  if row["Name"] == "Tannor Johnson":
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 0.2, y + 1.0),
                ha='left', va='center', rotation=0, wrap=True, color=color)
  elif row["Name"] == "Connor Holcombe":
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 0.2, y + 0.7),
                ha='left', va='center', rotation=0, wrap=True, color=color)
  elif row["Name"] == "Marisa Rafter":
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 0.8, y - 0.5),
                ha='left', va='center', rotation=0, wrap=True, color=color)
  elif row["Name"] == "Abbie Abramovich":
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 1.4, y + 0.2),
                ha='left', va='center', rotation=0, wrap=True, color=color)
  elif row["Name"] == "Hayley Wahlroos":
    ax.annotate(row["Name"], xy=(x, y), xytext=(x + 0.2, y + 0.7),
                ha='left', va='center', rotation=0, wrap=True, color=color)
  else:
    ax.annotate(row["Name"], xy=(x + adjustment, y + adjustment),
                ha='left', va='center', rotation=0, wrap=True, color=color)


Ryan Osgar has to win the title for "most valuable pick", being picked only twice (including by yours truly) while having the second highest fantasy score line. Although he was Minnesota's Callahan nominee, most users opted to go for his teammate Ben Jagt, who also ended with a similar fantasy score line. On the women's side, Dartmouth duo Zhu and Verzuh were the highest scoring players on fantasy, although most users opted for Jesse Shofner.

Ultimately, the best picks mostly came down to whether the team managed to survive deep into the tournament. UMass and UNC-W were eliminated by pre-quarters, limiting the scoring impacts of Tannor Johnson, Conor Kline, Jack Williams, and Xavier Maxstadt. UCF Shayna Brock seemed like a good choice prior to the tournament, due to the tight rotation UCF runs allowing Brock to get a lot of touches, but the same tight rotation (plus injuries) caused UCF to exhaust themselves early out of the tournament. Brock ended the tournament with 25 Turns and only 12 score contributions.

There were several strong picks who were passed over entirely by /r/ultimate, despite plenty of name recognization. Namely: Warshaeur (UNC) and Pawel Janas (Colorado) on the Men's side, and Keila Strick (Virginia) and Hardesty (Whitman) on the Women's side. The best lines with 0 /r/ultimate picks would be:

  • Men's: Aaron Warshauer (North Carolina), Pawel Janas (Colorado), Nathan Haskell (Georgia), Robert Patterson (Florida State), David Reshef (Harvard), Tarik Akyuz (Case Western Reserve), Walker Matthews (North Carolina)
  • Women's: Keila Strick (Virginia), Alex Hardesty (Whitman), Patricia Weicht (Colorado College), Alexandra Ode (Oregon), Nhi Nguyen (Colorado), Marlena Sloss (Whitman), Lorraine Guerin (Wisconsin)

In [13]:
# mens_fantasy_clean["Name (Team)"] = mens_fantasy_clean.apply(
#     lambda row: "{name} ({team})".format(name=row["Name"], team=row["Team"]), axis=1)
# womens_fantasy_clean["Name (Team)"] = womens_fantasy_clean.apply(
#     lambda row: "{name} ({team})".format(name=row["Name"], team=row["Team"]), axis=1)
mens_best_no_pick = mens_fantasy_clean[mens_fantasy_clean["Fantasy Picks"] == 0].head(7)["Name"].values
womens_best_no_pick = womens_fantasy_clean[womens_fantasy_clean["Fantasy Picks"] == 0].head(7)["Name"].values
mens_best_no_pick[0] = mens_best_no_pick[0] + "*"
womens_best_no_pick[0] = womens_best_no_pick[0] + "*"
usau.fantasy.compute_fantasy_contest_results(from_csv=True, min_players=0, display=False,
                                             fantasy_input={"no_r_ultimate":
                                                            {"Men": mens_best_no_pick,
                                                             "Women": womens_best_no_pick}})


Out[13]:
User Total Men's Women's
0 no_r_ultimate 417.6 219.2 198.4

Not bad, but also not great -- excluding /r/ultimate's picks, one could have still placed about midway in the fantasy contest. /r/ultimate did a good job of picking the top end picks for both gender divisions.

Fantasy variations

Just for fun, how would things have shaken up if the rules for fantasy had been perturbed a little bit? What happens if (1): we remove the captain multiplier, (2): we increase the weight of Ds and Turns, (3): we increase the weight of Ds and Turns even more?


In [14]:
usau.fantasy.compute_fantasy_contest_results(from_csv=True, min_players=0,
                                             display=False, captain_multiplier=1).head(5).reset_index().style \
  .bar(subset=["Total", "Women's"],
       color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=["Men's"],
       color='rgba(200, 80, 80, 0.5)')


Out[14]:
index User Total Men's Women's
0 12 ultimatefrisbee 402.6 219 183.6
1 7 grhgra002 386.8 210.8 176
2 11 scottyskin96 373.8 210.4 163.4
3 5 duthracht 370.6 185.2 185.4
4 6 giftedbadly 369.6 185.4 184.2

In [15]:
usau.fantasy.compute_fantasy_contest_results(from_csv=True, min_players=0,
                                             display=False, beta=0.5).head(5).reset_index().style \
  .bar(subset=["Total", "Women's"],
       color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=["Men's"],
       color='rgba(200, 80, 80, 0.5)')


Out[15]:
index User Total Men's Women's
0 12 ultimatefrisbee 427 237 190
1 11 scottyskin96 418.5 239.5 179
2 7 grhgra002 401.5 213.5 188
3 3 chubs45 399.5 204.5 195
4 8 krdonnie 396 236.5 159.5

In [16]:
usau.fantasy.compute_fantasy_contest_results(from_csv=True, min_players=0,
                                             display=False, beta=1.0).head(5).reset_index().style \
  .bar(subset=["Total", "Women's"],
       color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=["Men's"],
       color='rgba(200, 80, 80, 0.5)')


Out[16]:
index User Total Men's Women's
0 12 ultimatefrisbee 368 211 157
1 11 scottyskin96 355 205 150
2 3 chubs45 348 182 166
3 10 samth 341 189 152
4 7 grhgra002 333 180 153

Sigh, alright, /u/ultimatefrisbee, looks like we can't push you off the pedestal!

How about single-game fantasy? Here were the best performances by a player in a single game.


In [17]:
match_reports = pd.concat([usau.reports.d1_college_nats_men_2016.match_reports,
                           usau.reports.d1_college_nats_women_2016.match_reports])
match_reports['Fantasy Picks'] = 1
usau.fantasy.compute_athlete_fantasy_scores(match_reports) \
    [["No.", "Name","Fantasy Score", "Gs", "As", "Ds", "Ts", "Team", "Opp Team", "Score", "Opp Score"]].head(15).style \
  .bar(subset=['Fantasy Score', 'As', 'Ts'],
             color='rgba(80, 200, 100, 0.5)') \
  .bar(subset=['Gs', 'Ds'],
             color='rgba(200, 80, 80, 0.5)')


Out[17]:
No. Name Fantasy Score Gs As Ds Ts Team Opp Team Score Opp Score
1145 31 John Wodatch 11 2 9 1 1 Connecticut North Carolina-Wilmington 15 12
1776 21 Jaclyn Verzuh 10.4 6 5 1 4 Dartmouth Virginia 13 15
215 2 Jesse Shofner 10 2 8 2 2 Oregon California 15 10
1350 11 Janina Freystaetter 9.8 3 5 10 1 Central Florida Ottawa 15 2
64 3 Khalif El-Salaam 9.8 4 6 1 2 Washington Texas A&M 13 15
1949 14 John Stubbs 9.2 4 6 0 4 Harvard North Carolina 13 11
2270 23 Mark Vandenberg 9.2 3 6 3 2 Harvard Oregon 15 13
633 8 Angela Zhu 9 1 8 1 1 Dartmouth Pittsburgh 15 3
495 2 Robert Patterson 8.8 0 9 2 3 Florida State North Carolina 14 16
611 27 Connor Holcombe 8.8 7 2 0 1 Florida State Colorado 12 15
1394 4 Lorraine Guerin 8.6 5 3 6 3 Wisconsin Texas 14 15
49 13 Dalton Smith 8.6 3 6 1 3 Texas A&M Washington 15 13
2265 14 John Stubbs 8.6 5 4 1 3 Harvard Oregon 15 13
746 23 Tarik Akyuz 8.4 3 5 3 1 Case Western Reserve North Carolina 15 16
469 0 Aaron Warshauer 8.4 4 4 3 1 North Carolina Florida State 16 14

While Stubb's first half vs UNC was the material of legends, surely John Wodatch's insane performance versus UNC-W has to go down as the best single player performance in a single game this tournament. Wodatch combined for 11 of 15 UConn's points of the game while only throwing one turnover (and making up for it with a D). Verzuh also was everywhere for Dartmouth in their quarterfinals loss to Virginia. Interestingly, both Dalton Smith and Khalif El-Salaam end up on this list, while matching up against each other in their pool play game.

Have other thoughts for content you'd like to see? I've love to hear it, reach out to me at azjps@github or azjps@reddit.