featured-image

Warriors Ready to Make a Splash With Analytics

Established 1946 | 7-time NBA Champions

You know the drill. You want a quick recap of the game, so you go straight to the box score. It tells you the basics, who won, who put up big numbers, and who didn’t. But we all know there’s so much more to the story. So many chapters that don’t make the jump from the hardwood to the stat sheet. That is, until now.

The Warriors and MOCAP Analytics want to bring you, the fan, closer to the action. We know it’s tough to tell a good sports story without getting into numbers, but we also think it’s time to add a little color to the narrative. Time to add some words and visualizations to the traditional play-by-play.

So, here we go.

We’ll use the first eight Warriors games from this season to bring you the digital-age enhancement to the print-friendly box score. Those of us who remember getting ink on our fingers as we flipped through the sports page know exactly what I'm referring to.

MOCAP Action Cloud:

If you tally up the box scores from the first eight games of the season, you’ll find the Warriors near the top of the NBA in field goal percentage (49.3 percent) and three-point percentage (43.7 percent), while also being one of the stingiest defenses in the NBA, holding opponents to 41.2 percent from the field and 27.6 percent from behind the arc. However, the box score does little to elaborate on what’s actually working on each side of the ball. The Action Clouds above provide visual representations of the offensive and defensive actions that the Warriors have had success with over the first two weeks of the season. The size of each phrase in the cloud represents the effectiveness of that particular kind of play, with larger text meaning greater success on offense (blue cloud) or defense (yellow cloud). At a glance, you’ll notice the Warriors are playing great team basketball, moving without the ball (“Cutting Lanes”), creating for others off the bounce (“Middle Drive & Kick”), and finding perimeter shooters (“Spot Ups”). On the defensive end, the Warriors are doing a great job of defending drives (“Baseline Drives”), stifling plays from the elbows (“High Post Touch”), and disrupting opponents’ “Two Man Game.”

It should come as no surprise that the Warriors are blessed with terrific shooters, but the improvement on defense this season has been a bit of a revelation. Golden State is the only team in the NBA to rank in the top six in both points per possession and points per possession allowed, and these action clouds dive deeper into explaining exactly how that’s being accomplished.

MOCAP Heat Check:

The MOCAP Heat Checks shown above display each starter’s frontcourt touches over the first eight games. As you’d expect, Stephen Curry and Klay Thompson get most of their touches out on the perimeter. Andre Iguodala’s immense versatility is evidenced by his splattering of touches throughout the frontcourt, while David Lee and Andrew Bogut, both skilled playmakers, have proven they can work on the block as well as handle the ball on the perimeter.

MOCAP Arc:

Pick and rolls are a huge part of today’s game, and when it comes to the Warriors, it’s an elemental part of their offense. The Action Arc above shows the combinations of Warriors’ ball handlers and screeners that worked together on pick and rolls over the first eight games. When you hover over Curry, or any other player on the “Handler” half of the Arc (yellow), you’ll find all the players that set screens for him. Similarly, when you hover over Lee, or any other player on the “Screener” half of the Arc (blue), you’ll see all the handlers he set screens for. As you can see from the web of connections between players, the Warriors (surprise, surprise!) clearly have many effective options on the offensive end.

Where did this data come from?

Back in 2011, the Warriors became one of the first teams in the NBA to install the STATS LLC SportVU camera tracking system in their home arena. This season all 30 teams in the league are using this same system, a big nod to the promising future of analytics within the sport. Using SportVU, every player movement on the floor is tracked and stored, and later digested to help show how things happened in the game.

In order to process all of the tracking data collected by SportVU, the Warriors have teamed up with MOCAP Analytics, a Silicon Valley technology startup. MOCAP has developed an analytics platform to interpret the data, and provide relevant, actionable information to the team staff. Using MOCAP’s platform, we also have the opportunity to share creative content that will give you both the real story of what happened on the court, and an edge in your next water cooler showdown.

These are just a few examples of interactive content that can be created utilizing the data attained by SportVU, and the platform engineered by MOCAP. While it is a lot of new information to take in, the goal is to provide you, the fans, with the basic knowledge and vernacular of basketball from the bench, to introduce valuable insights about the game you love. We’ll be sharing more of this digital content throughout the season, and look forward to expanding the narrative available for anyone who seeks it. Granted, this kind of information can be highly sensitive, and while we certainly won’t compromise any competitive advantage by divulging too much, we also know that we have intellectual, tech-savvy fans that might enjoy such information, and thus, hope to involve them in the process.

 

The opinions expressed in this article are those of the writer and do not necessarily reflect the views of the Golden State Warriors.

 

$(document).ready(function() { $('.tab-image-nav-btn').click(function(e) { e.preventDefault();

var tabImageID, tabImageSrc;

tabImageID = $(this).attr('data-image-id'); tabImageSrc = $(this).attr('data-image-src');

$(this).siblings().removeClass('tab-image-nav-btn-active');

$(this).addClass('tab-image-nav-btn-active');

$('#' + tabImageID).attr('src', 'https://i.cdn.turner.com/nba/nba/.element/media/2.0/teamsites/warriors/images/' + tabImageSrc); }); });

var labels = { 0:'LeeS', 1:'BogutS', 2:'SpeightsS', 3:"O'NealS", 4:'GreenS', 5:'KuzmicS', 6:'ThompsonS', 7:'IguodalaS', 8:'BarnesS', 9:'GreenH', 10:'BarnesH', 11:'BazemoreH', 12:'ThompsonH', 13:'NedovicH', 14:'DouglasH', 15:'IguodalaH', 16:'CurryH', }; ids = { 'David LeeS':0, 'Andrew BogutS':1, 'Marreese SpeightsS':2, "Jermaine O'NealS":3, 'Draymond GreenS':4, 'Ognjen KuzmicS':5, 'Klay ThompsonS':6, 'Andre IguodalaS':7, 'Harrison BarnesS':8, 'Draymond GreenH':9, 'Harrison BarnesH':10, 'Kent BazemoreH':11, 'Klay ThompsonH':12, 'Nemanja NedovicH':13, 'Toney DouglasH':14, 'Andre IguodalaH':15, 'Stephen CurryH':16, };

screen_data = [{'c': 2, 'o2': 'Klay Thompson', 'o1': 'Kent Bazemore'}, {'c': 1, 'o2': "Jermaine O'Neal", 'o1': 'Kent Bazemore'}, {'c': 15, 'o2': 'Marreese Speights', 'o1': 'Kent Bazemore'}, {'c': 3, 'o2': 'Draymond Green', 'o1': 'Kent Bazemore'}, {'c': 8, 'o2': 'Ognjen Kuzmic', 'o1': 'Kent Bazemore'}, {'c': 2, 'o2': 'Marreese Speights', 'o1': 'Draymond Green'}, {'c': 11, 'o2': "Jermaine O'Neal", 'o1': 'Draymond Green'}, {'c': 1, 'o2': 'Klay Thompson', 'o1': 'Draymond Green'}, {'c': 1, 'o2': 'Andre Iguodala', 'o1': 'Draymond Green'}, {'c': 15, 'o2': 'David Lee', 'o1': 'Klay Thompson'}, {'c': 3, 'o2': "Jermaine O'Neal", 'o1': 'Klay Thompson'}, {'c': 7, 'o2': 'Marreese Speights', 'o1': 'Klay Thompson'}, {'c': 10, 'o2': 'Andrew Bogut', 'o1': 'Klay Thompson'}, {'c': 2, 'o2': 'Draymond Green', 'o1': 'Klay Thompson'}, {'c': 19, 'o2': "Jermaine O'Neal", 'o1': 'Andre Iguodala'}, {'c': 28, 'o2': 'Andrew Bogut', 'o1': 'Andre Iguodala'}, {'c': 8, 'o2': 'Marreese Speights', 'o1': 'Andre Iguodala'}, {'c': 6, 'o2': 'Harrison Barnes', 'o1': 'Andre Iguodala'}, {'c': 26, 'o2': 'David Lee', 'o1': 'Andre Iguodala'}, {'c': 8, 'o2': 'Klay Thompson', 'o1': 'Andre Iguodala'}, {'c': 1, 'o2': 'Draymond Green', 'o1': 'Andre Iguodala'}, {'c': 7, 'o2': 'Andrew Bogut', 'o1': 'Harrison Barnes'}, {'c': 5, 'o2': "Jermaine O'Neal", 'o1': 'Harrison Barnes'}, {'c': 6, 'o2': 'Marreese Speights', 'o1': 'Harrison Barnes'}, {'c': 1, 'o2': 'David Lee', 'o1': 'Harrison Barnes'}, {'c': 16, 'o2': "Jermaine O'Neal", 'o1': 'Stephen Curry'}, {'c': 58, 'o2': 'Andrew Bogut', 'o1': 'Stephen Curry'}, {'c': 14, 'o2': 'Andre Iguodala', 'o1': 'Stephen Curry'}, {'c': 18, 'o2': 'Marreese Speights', 'o1': 'Stephen Curry'}, {'c': 10, 'o2': 'Harrison Barnes', 'o1': 'Stephen Curry'}, {'c': 58, 'o2': 'David Lee', 'o1': 'Stephen Curry'}, {'c': 12, 'o2': 'Klay Thompson', 'o1': 'Stephen Curry'}, {'c': 22, 'o2': 'Draymond Green', 'o1': 'Stephen Curry'}, {'c': 10, 'o2': "Jermaine O'Neal", 'o1': 'Toney Douglas'}, {'c': 3, 'o2': 'Andrew Bogut', 'o1': 'Toney Douglas'}, {'c': 4, 'o2': 'Andre Iguodala', 'o1': 'Toney Douglas'}, {'c': 9, 'o2': 'Ognjen Kuzmic', 'o1': 'Toney Douglas'}, {'c': 33, 'o2': 'Marreese Speights', 'o1': 'Toney Douglas'}, {'c': 1, 'o2': 'Harrison Barnes', 'o1': 'Toney Douglas'}, {'c': 8, 'o2': 'David Lee', 'o1': 'Toney Douglas'}, {'c': 1, 'o2': 'Klay Thompson', 'o1': 'Toney Douglas'}, {'c': 3, 'o2': 'Draymond Green', 'o1': 'Toney Douglas'}, {'c': 3, 'o2': "Jermaine O'Neal", 'o1': 'Nemanja Nedovic'}, {'c': 10, 'o2': 'Marreese Speights', 'o1': 'Nemanja Nedovic'}, {'c': 8, 'o2': 'Draymond Green', 'o1': 'Nemanja Nedovic'}, {'c': 17, 'o2': 'Ognjen Kuzmic', 'o1': 'Nemanja Nedovic'}];

var fill = d3.scale.ordinal() .domain(d3.range(7)) .range([ //"rgb(63,0,125)", //purple //"rgb(127,59,8)", //brown //"rgb(72,72,72)", //grey //"rgb(255,127,0)", //orange //"rgb(197,27,125)", //pink //"rgb(197,197,197)", //dark grey "rgb(33,102,72)", //blue //"rgb(0,104,55)", //green //"rgb(188,0,38)", //red //"rgb(188,0,38)", //red "rgb(255,217,47)", //yellow

]);

var previous_color = 'blue'; function color_pick(index){ console.log(index); yellow = "hsl(209,95%,31%)"; blue = "hsl(45,100%,60%%)"; if ( typeof index == 'undefined' ){

//if (previous_color == 'blue') { if (false) { previous_color = 'yellow'; return yellow; } else { previous_color = 'blue'; return blue; } } else { if (labels[index].slice(-1) == 'S') { return yellow; } else { return blue; } } }

fill = color_pick;

var screen_matrix = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ];

for (var i = screen_data.length; i>0; i--) { var screen = screen_data[i-1], p1 = ids[screen.o1 + "H"], p2 = ids[screen.o2 + "S"], c = screen.c;

console.log(screen.o1); console.log(screen.o2); console.log(p1); console.log(p2); console.log(c);

screen_matrix[p1][p2] += c; screen_matrix[p2][p1] += c; }

var chord = d3.layout.chord() .padding(.05) .sortSubgroups(d3.descending) .matrix(screen_matrix);

var w = 470, h = 470, r0 = Math.min(w, h) * .28, r1 = r0 * 1.1;

var svg = d3.select("#viz") .append("svg:svg") .attr("width", w) .attr("height", h) .append("svg:g") .attr("transform", "translate(" + w / 2 + "," + h / 2 + ") " + "rotate(0)" )// + "," + w / 2 + "," + h / 2 + ")") ;

svg.append("svg:g") .selectAll("path") .data(chord.groups) .enter().append("svg:path") //.style("fill", "white" ) //.style("stroke", "white" ) .attr("d", d3.svg.arc().outerRadius(r1));

svg.append("svg:g") .selectAll("path") .data(chord.groups) .enter().append("svg:path") .style("fill", function(d) { return fill(d.index); }) .style("stroke", function(d) { return fill(d.index); }) .attr("d", d3.svg.arc().innerRadius(r0).outerRadius(r1)) .on("mouseover", fade(0.1)) .on("mouseout", fade(1)); var ticks = svg.append("svg:g") .selectAll("g") .data(chord.groups) .enter().append("svg:g") .selectAll("g") .data(groupTicks) .enter().append("svg:g") .attr("transform", function(d) { return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" + "translate(" + r1 + ",0)"; });

ticks.append("svg:line") .attr("x1", 1) .attr("y1", 0) .attr("x2", 5) .attr("y2", 0) .style("stroke", "#FFF");

ticks.append("svg:text") .attr("x", 8) .attr("dy", ".35em") .attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) .attr("transform", function(d) { return d.angle > Math.PI ? "rotate(180)translate(-16)" : null; }) .style("fill", 'white') .text(function(d) { return d.label.slice(0,-1); });

svg.append("svg:g") .attr("class", "chord") .selectAll("path") .data(chord.chords) .enter().append("svg:path") //.style("fill", function(d) { return fill(d.target.index); }) .style("fill", function(d) { return fill(); }) .attr("d", d3.svg.chord().radius(r0)) .style("opacity", 1);

/** Returns an array of tick angles and labels, given a group. */ function groupTicks(d) { var k = (d.endAngle - d.startAngle) / d.value; return d3.range(0, d.value, 1000).map(function(v, i) { return { angle: v * k + d.startAngle, label: labels[d.index] //label: i % 5 ? null : v / 1000 + "k" }; }); }

/** Returns an event handler for fading a given chord group. */ function fade(opacity) { return function(g, i) { svg.selectAll("g.chord path") .filter(function(d) { return d.source.index != i && d.target.index != i; }) .transition() .style("opacity", opacity); }; }

$(function() { $("#nbaPollsVote-69426 #edit-vote").click(function(e) { $("#vote-swap").attr('src', 'https://i.cdn.turner.com/nba/nba/.element/media/2.0/teamsites/warriors/images/mocap_touches_dark_lee_576x595.jpg'); }); });

Tags