This is my first attempt at making data visualization in Tableau after almost four and a half years. I recently have decided to start doing more data side projects. I really enjoy doing them and this dashboard was my attempt to refamiliarize myself with Tableau. To think there was a time when I was Tableau Certified and used the platform daily.
Anyways, it took a little bit to feel comfortable. But I’m happy with my first dashboard.
About the Dashboard
The dashboard below uses the Superstore data, which is probably the most used data set for Tableau projects. I figured for my first project back that I should use a tried and true data set.
The business scenario I was looking to answer was “How do I view sales by segment for each of the four regions?” I could see a director of sales wanting to know this information.
I wanted to challenge myself a bit, so I made the dashboard interactive. Instead of using one of Tableau’s built in filters, I wanted to try my hand at a stylized bar that also displays data. You can filter the data in each panel by segment by clicking on the bar at the top. The segment bar shows total sales for each segment. And when you click on a specific segment it will be highlighted in red and then filter the data in the panels below. To do this I had to create a parameter and then a calculated field. As well as do some slick stylizations.
A lot of working with Tableau is using tips, hacks, and workarounds to get things to look how you want. The Tableau hacks rabbit hole is deep. This was me dabbling a little bit and showing off some knowledge of the platform.
Continuing, the dashboard consists of four panels. One panel for each region. At the top of each panel is a KPI which is total sales for that region. Below that is a time series bar chart showing the last 12 months of sales. After that it shows a map highlighting which states in each region had the highest number of sales.
I generally don’t like maps. As the data almost always correlates with population. It’s not helpful to know that the states with the most people have the most sales. And that does happen to some extent with these maps, but not too much. Especially in the South region.
And then the final graph in the panel is a bar chart showing which subcategories had the most sales in descending order.
So with this dashboard, an executive can quickly find out the total sales for a region, which state is producing the most sales, and know which how the sub categories are performing in each region.
I decided to make the dashboard Meijer themed because A) businesses always prefer their dashboards to be branded. When I did Tableau work for GM and Hershey, they always wanted logos and branding over everything. and B) Meijer is my favorite grocery store from Michigan and I miss it.
In conclusion, I’m happy with how this dashboard turned out. It’s not doing anything complex from a data standpoint, but that was never the goal. I wanted to reacquaint myself with Tableau since it had been a few years, and I feel like I’ve accomplished that and made a nice data visualization in the process.
Sports data is great because it’s usually pretty clean and everyone is familiar with how sports work. Economic data from FRED, while great, has a learning curve. So I decided to venture into pulling some NFL data to get started.
My first attempt at pulling the data was to use Python’s Beautifulsoup library to scrape it off of https://www.pro-football-reference.com/. It’s a great site with all the stats you could want. It’s also very difficult to scrape data from. And when I did some research, it looks like no one has been able to scrape data from it for a few years. All the GitHub repositories are from around 2019. This makes sense. If I were Pro-Football-Reference I would also design my site to be impossible/difficult to scrape. So i had to find another solution and I did.
Thank goodness Python has a robust community. Because I was able to find the NFL-data-py library and use it to import data. It’s a library that has tons of NFL stats going back to 1999, so twenty-five years. So with that library found I was able to quickly whip up a python script in Repl.
Below is the Python script I used to pull the data.
import pandas as pd
import nfl_data_py as nfl
import pandasql as ps
print(nfl.see_weekly_cols())
##Variables
years = list(range(1999, 2025))
QBcolumns =['player_id', 'headshot_url', 'recent_team',
'player_display_name','passing_yards','position','season',
'week','completions','attempts','passing_tds','interceptions',
'sacks', 'sack_yards', 'sack_fumbles', 'sack_fumbles_lost',
'passing_air_yards', 'passing_yards_after_catch', 'passing_first_downs',
'rushing_yards', 'rushing_tds']
##########################
##QB Table
##########################
QBstats = nfl.import_weekly_data(years, QBcolumns)
QBquery = "SELECT * FROM QBstats WHERE position = 'QB'"
QB2000s = ps.sqldf(QBquery, locals())
baseline_season = QB2000s['season'].min()
# Calculate a continuous variable: total weeks since baseline
QB2000s['season_week_index'] = (QB2000s['season'] - baseline_season) * 17 + QB2000s['week']
QB2000s.to_csv("QB-data-2000s.csv", index=False)
print("QB CSV exported")
So let me walk through this code quickly. First I imported all the necessary libraries. Pandas for working with data. nfl_data_py to pull the NFL data. And, pandasql because I wanted to throw some SQL in there just to get some practice. Originally I thought the query I’d be doing would be more interesting, but ultimately it turned out to be a rather lame SQL query and is entirely superfluous. Regular pandas could have easily handled it.
I pull the NFL data into QBstats using nfl.import_weekly_data() function. It takes two inputs a list of years and a list of columns. Both of those variables were created under the variables section.
After that I used SQL to select on the the Quarterbacks.
For this data I had Seasons and Weeks, which sounds like dates, but actually isn’t. It’s more just the nomenclature the NFL uses. Next I had to create a week index. Dealing with dates is always a pain and it’s more of pain when the dates aren’t tired to a calendar. But the work around I came up with was to create a week index.
To create an index, I took a baseline(aka the minimum) of the seasons, and then subtracted that value from all the season in the data set. Next, I multiplied that by 17, because there are 17 weeks in an NFL season. And then added the week to the respective season. This created a continuous index that would allow me to post the QB passing data in a time series.
Last I exported it all to a CSV and loaded it into Tableau.
In Tableau, I used a table calculation on Passing Yards to get a running total. This was how I made the main graph. And then I used Dashboard actions to make the the graph filter when you clicked on a specific line. Similar to my last Tableau Dashboard(The Meijer Superstore), I created a parameter and a calculated field so that when you clicked on the lines the selected line would turn red.
Wrap Up
Overall, the end result is not has impressive as I hoped it would be. I spent way too much time on trying to scrape the data and failing and then looking for an alternative way to acquire NFL data. I also spend too much time fighting with date data, and realizing I needed to make an index of weeks.
Once I had it, the dashboard came together rather quickly.
It was good experience even if the end result is a little lack luster. When working with data the hardest parts are often getting the data and transforming the data, and this project was right in line with that. But I do think rediscovering date indexes the hard way was a valuable lesson and a strategy I won’t soon forget.
Anyways, on to the next!