
The season went fast. It always does.
I launched this project on October 22, minutes before the tip off of the season’s first game — Celtics vs. Knicks. At that time, it was a simple, non-interactive table featuring team, average rank, and variance, to measure how differently outlets saw the future of these teams.
Now, 6 months later, I’ve compiled and analyzed over 100 sets of power rankings from top media sources, including ESPN, NBA.com, Bleacher Report, theScore, and Fox Sports, and transformed this data into an immersive and interactive dashboard app, with multiple visualization options and views.
Here’s how I did it and what I learned.
Process
I used BeautifulSoup
to scrape power rankings stories by ESPN, NBA.com, Bleacher Report, theScore, Fox Sports, CBS Sports, and more, saving the data (including the comments) to a CSV file.
Future versions of this project could include a qualitative analysis of the comments, which could provide some interesting context for the way the season has unfolded, but for this year, I wanted to focus more specifically on the numerical performances of the teams.
I developed modules to aggregate out the individual data points to a week of the season, as well as some to hold unchanging, team-related data.
I aggregated the data in pandas
using a pivot table to chart the mean, min, and max rankings for each team for each week of the season.
Here is the aggregated data. I’ve since added measures of standard deviation, max 1-week change, and created sparklines to help tell the story visually. I’ve deployed the DataFrame via Streamlit.
Then I created preliminary, static visualizations using MatPlotLib
. I created a chart that showed the whole league’s performances, and then I picked out interesting teams whose performance I wanted to highlight in solo charts.
I wanted to be able to interact with the graph, though, so I decided to learn Plotly
and Dash
.
In Dash
, I added filters and views: the ability to filter the view by date, to highlight top and bottom positions, adjusting the view by rank, and toggling data points. Then I added a searchbar and All Teams toggle for smoother exploration.
And then, as most storytellers will tell you, I made my story better by saying less. I hid some of the view controls, I removed a ton of x- and y-ticks. I simplified.
And then I simplified even further. If the “spaghetti” chart was overwhelming to me, imagine how overwhelming it could be to someone coming to my visualization for the first time! So I made the decision to deemphasize that “whole league” chart in favor of an easier point-of-entry: a single team chart. The single team chart is a clean, simple landing page, which shows just one team’s performance at a time. And because of this cleanliness, I was able to add two more views, both of which I am really excited about.
Firstly, I created a graph that maintains a focus on the team’s power rankings performance and adds context for the highs and lows of how that team has been assessed. Though it averages out to the same score, a team that everyone places 14th or 15th is, of course, a different beast from a team that some outlets rank 8th and some rank 20th! I am really pleased with how this chart turned out.
The other secondary chart compares a team’s power ranking performance to their actual games performance by looking at the 20-game win%. At first, I used an API to track the team standings, but I quickly pivoted to scraping from trusty basketball-reference.com, which has historic standings data day-by-day. By placing this plot on the same chart (different axes), we can see how closely — or not — the team’s on-court performance correlates to their perception in the media.
Wrap-Up
Now that we’re in the playoffs, most outlets have shelved their power rankings series for the year. I’ll follow their lead.
But I may bring back this series for next year, with more features and context.
It’s been fascinating to learn about the league and about data and data visualization through this hands-on project.
And it’s been a very interesting way to follow the season! I find my appetite for NBA coverage really varies based on how well my Warriors play. I might tune out for a week or more if they’re slumping. But this project allowed me to follow the rises and falls of the league in a more succinct and more evenhanded way, as opposed to being swayed (and exhausted) by the highly reactive and theatrical league coverage that can dominate the landscape. Personalities, trade rumors, speculation; none of it really ends up being more important than each team’s outcomes.
If you’re passionate about the NBA, or if you have a basketball fan in your life, I’d love to hear from you! What surprises you? What sticks out?
Leave a Reply