albertlyu / shot-charts-site Goto Github PK
View Code? Open in Web Editor NEWA Rails web application for visualizing NCAA men's basketball play-by-play shot location data
License: MIT License
A Rails web application for visualizing NCAA men's basketball play-by-play shot location data
License: MIT License
Also optional. http://railsapps.github.io/rails-google-analytics.html
Rotate the shot charts and background image so that the hoop is on the top and the chart is from the offense's perspective instead of from the defense's perspective. But don't work this issue until #43 is resolved.
Add a player search and autocomplete bar. See the pitchfx-site for examples. Or maybe Elasticsearch? https://shellycloud.com/blog/2013/10/adding-search-and-autocomplete-to-a-rails-app-with-elasticsearch
Remove the play-by-play from the team and player pages, and add the play detail as tool tips to the shots in the shot charts.
Create a game page for each game. Show all the plays for that game.
Currently, the teams and players pages have shot charts. Add shot charts to the game pages too. This would be useful for browsing a team's game log or NCAA Tournament games.
Based on games selected, aggregate basic counting stats and calculate rate statistics. See www.hoopdata.com.
Select a charting library from http://selection.datavisualization.ch/ with scatter plots and bubble charts. Let's consider:
I think Highcharts is the best since I have some familiarity with it due to using it for BaseballMod.com.
Alright, some of our queries are super inefficient, and I think they could greatly be improved in terms of readability and performance with some ETL updates to the database. So add a new column to the plays
table and write migration scripts to update that column for every shot with x_coord
and y_coord
. The name of the column will be zone_desc
or zone_id
if we have a new lookup table called zones
or something. Once this is done, then we can more easily create shot statistics based on location.
Let's use the shot zones from 82games. See:
http://www.82games.com/locations.htm
http://www.82games.com/shotzones.htm
I think the migration script will look something like this:
class CreateZones < ActiveRecord::Migration
def change
create_table :zones, id: false do |t|
t.primary_key :zone_id
t.string :zone_desc
t.timestamps
end
end
end
Improve the Draft 3.0 view. Maybe have a table of statistics for all 50 players. Possibly an accordion to organize the buckets of players.
Potential big bug here. Investigate x_coord for shots for a particular game, for the home team or away team, 1st half or 2nd half, each of the four combinations. First discovered this potential bug by looking at game_id = 87768 (New Mexico vs. Alabama A&M on 2013-11-09). For reference: http://sportsillustrated.cnn.com/basketball/ncaa/men/gameflash/2013/11/09/87768/index.html#live
It may make more sense to investigate this potential issue for a tournament game, where we can easily find a full game replay somewhere, and chart some shots by hand.
I don't see any real-time updates with Google Analytics tracking after fixing #23. I'll open this issue to work on fixing tracking.
Review the following links as necessary:
https://support.google.com/analytics/answer/1008080?hl=en&utm_id=ad
http://railsapps.github.io/rails-google-analytics.html
Then check the 'Real-Time Overview' page to see live updates within seconds. Also check if "Status: Tracking Not Installed" has been updated on the 'Tracking Code' page under 'Tracking Info.'
Optional, after the Draft 3.0 deadline. https://rpm.newrelic.com/accounts/682896/applications/setup
The team pages could use player stats now.
For deployment to Heroku (if we choose that as the app hosting site), SQLite will not be ideal as a production database. Let's replace the SQLite database with PostgreSQL, or at the very least, create and manage a process for deploying a database to production as a Postgres database. Replacing SQLite db with Postgres db altogether will incentivize continuous deployment.
Hopefully this won't take too much work. This link on Heroku's Dev Center site will help: https://devcenter.heroku.com/articles/sqlite3
If basic stats table completed, scaffold a similar table with advanced stats (eFG%, TS%, etc.). Add some interesting shot location statistics to the player page. Outsource the calculations to javascript for this. Things such as FG% at rim, FG% from certain distances, etc. Follow the standard set by Hoopdata (http://hoopdata.com/player.aspx?name=LeBron%20James).
Instead of showing all Division I teams on the home page, add a team navigator similar to what we see at www.BaseballMod.com. Show the 'high major' conferences, and allow the end-user to select a conference, then select a team, then select a player, and move back and forth between the views before choosing a player. We shouldn't have to force the end-user to go through the team page to get to a player that they want to see the player page of.
Could use animate.css (#37) for this. But the transition from conferences to teams to players on click would have to use jQuery or something, since BaseballMod.com's AngularJS framework allowed the properties ng-click
, ng-show
, ng-hide
, etc. We'd have to find an alternative in our Rails framework.
The Highcharts shot charts with the tooltips are nice. However, there is a lot of noise with a scatter chart. A heatmap would be nice as a shot frequency chart. We can also create a shot efficiency chart by weighting the points by 2, 3, or 0 depending on if the shot was a 2-pt field goal made, a 3-pt field goal made, or field goal missed.
Perhaps heatmap.js would be nice for this - the downside is no tooltips. Maybe that's okay. We can use this example. http://www.patrick-wied.at/static/heatmapjs/examples.html
For deploying to Heroku as a production-grade app, we may need to replace the out-of-the-box rails server WEBrick with a more production-grade server such as thin. So add thin
to our Gemfile.
Instead of ordered lists, create Bootstrap button groups for teams, players, possibly games.
I'm currently exceeding the Hobby-dev row limit of 10,000 by almost 7500%. Upgrade to Hobby-basic ASAP before Heroku shuts the site down.
Currently, the About link in the nav bar directs to nothing. So add an About page with with information on the application as well as contact information.
Use the ActiveRecord query for basic stats and shot stats and add a leaderboards view for all qualified players (min. 100 shots?). Make this leaderboards table sortable, similar to what we see in the Draft 3.0 view.
Gotta add a background image to the shot charts on the player pages that will re-size responsively.
Fix associations between team, player, play models so that we can implement Rails 'shortcuts' to grab plays associated with a player, players associated with a team, etc. Also may have to rename the Playergame model to PlayerGame (playergame.rb
to player_game.rb
, etc.).
Follow the convention set in the Rails app here: https://github.com/albertlyu/rails-workshop/tree/master/store.
According to New Relic (which monitor's app performance), the queries to grab plays or shots statistics are causing some pages to load quite slowly. 5-6 second page loads are not good at all. We'll need to investigate how to write more optimal queries, particularly the shot statistics in the draft view, as I believe the page load time is due to this.
Additionally, we'll need to figure out how to test this in our dev environment. Most likely it'll be monitoring the rails server logs while navigating the pages locally, but it may be worth our time to investigate continuous integration, testing and performance tools for Rails apps.
Add box score to the game pages. Pull all the data from player_games for a particular game_id. I believe we can use the boolean 'starter' to show the starters first, then rank by minutes I suppose.
ActiveRecord models keep showing up at the bottom of the lists of conferences, teams, and players. Fix the application erb files so that this stops happening.
Might have to convert the numerator of the per-40 stats on the player pages to a float to get this right.
The mobile UX is not good, mostly because of the sidebar. Let's update the app so that the sidebar is hidden, or get rid of the sidebar altogether.
Add NCAA Tournament game log view with a link to each game.
Pending completion of #4.
The player pages currently have a basic stats table as well as a shot statistics table. However, the Draft 3.0 view does not have the latter. Add shot statistics to the Draft 3.0 view so that we can compare different shot location statistics across Draft 3.0 players. We might have to create a new view for this, or a drop down to swap between the basic stats view and the shots stats view.
Create a draft page for the Top 50 players from the Draft 3.0 challenge. Also add a link to the Draft 3.0 50 players in the side navbar.
See https://github.com/albertlyu/shot-charts-site/blob/master/draft3.0/players.txt for players, https://github.com/albertlyu/shot-charts-site/blob/master/draft3.0/players.csv for player IDs.
Splitting off from #33, create a shot efficiency heatmap of expected point value, some sort of surface regression of point value by shot location.
Add player game log stats to player page.
Add an asterisk or footnote to each shot stats table mentioning that limited shot location is available. Or add a count to show how many shots have shot location available out of total shots taken by the player.
Run gem install animate-rails
and add gem 'animate-rails', '~> 1.0.5'
to the Gemfile. After that, add in some fadeInLeft
or even some slideInLeft
animations, perhaps for the conf/team/player buttons.
Let's not go crazy with the transitions, but rather, use them subtlely to enhance the look and feel of the site. Remind the end user that this site is built in HTML5 with some impressive but not annoying animations.
Let's deploy the Rails app to Heroku. Let's begin continuous deployment during the development of the app as soon as possible.
Once #3 has been decided, create scatter plots and possibly bubble charts of shots for the player pages in player.html.erb. This is going to be the fun part of the web app development.
One problem with the shot charts is that we don't have a good idea of at-rim shots as a percentage of all shots by looking at these charts. One good way to show at-rim shots as a percentage of all shots taken (as well as layups vs. dunk) is a stacked bar chart.
So let's create a stacked bar chart of shot types. Column detail_desc
from the plays
table, when you filter the play type for shots only, has five types of shots: Jump Shot, Hook Shot, Tip Shot, Layup, and Dunk Shot.
Also, once #48 is completed, we can also add a stacked bar chart for shot zone distribution.
Here's are some nice Highcharts examples of stacked bar charts here:
Stacked bar chart - http://www.highcharts.com/demo/bar-stacked
Stacked percentage column chart - http://www.highcharts.com/demo/column-stacked-percent
Stacked percentage bar chart - http://jsfiddle.net/LtG44/1/
Currently, only Memphis is categorized as an AAC team. The following teams need to have their team conferences updated to aac:
Louisville (bige)
Connecticut (bige)
Cincinnati (bige)
Temple (atl10)
SMU (cusa)
Houston (cusa)
South Florida (bige)
UCF (cusa)
Rutgers (bige)
There may be other teams that aren't in their updated conferences, but the AAC / Big East / Conference USA / Atlantic-10 are the important ones to be accurate.
Accordion transitions are only working on the player and team pages where the shot chart is rendered. This could possibly be due to a dependency being loaded by the Highcharts that isn't loaded by the rest of the app. I thought it was bootstrap-transition and bootstrap-collapse components, but they should be loaded by the rest of the app I believe.
Anyway, this has been labelled as a bug, though not a very important one, so work on this if time permits to enable bootstrap transitions for the other static pages.
Instead of team buttons, let's add shot statistics from the TeamShotStat model to the teams view and see the performance of the app in loading that page. In this way, we can compare teams based on where they like to shoot, and how well they shoot in each zone.
I think this is a more permanent solution to the issue raised up in #41 than optimizing the queries. The queries against the plays
table are taking the longest because every row is being checked to see if x_coord
is null. That's extremely inefficient for a non-indexed column.
So let's create and populate a new shots
table, only with shots that have x_coord
and y_coord
available.
Additionally, from #46, add a zone_id
for a shot's zone. We'll also create lookup tables for zones
and details
with the descriptions of zone and detail in each table (detail being the shot type such as 'Jump Shot,' event being example 'Field Goal Missed.').
gem install ember-rails, also uninstall twitter-bootstrap-rails, and use the bootstrap-sass gem instead. https://medium.com/p/b11cf922408d
For the stats tables in the draft, player, and team views, add header labels for the stats. That way, we can keep the headers shorter in width to fit more stats in the tables.
Similar to the shot chart data partial (https://github.com/albertlyu/shot-charts-site/blob/master/app/views/data/_shot_chart.html.erb#L1), add an embedded erb statement to render the basic stats or shot stats tables only when the necessary denominator stats and play-by-play data exist (field goals attempted, etc). These tables work for most BCS players, but not for many Div-IA players where play-by-play is scarce or non-existent.
With the new boxscore json files thanks to albertlyu/ncaab-pbp#4, we'll need to generate new ActiveRecord models for teamgames
and playergames
as well as recreate and reseed the players
table in the database. Modify seeds.rb
with care, as we don't want to re-seed the very large plays
table.
We can generate the models like so:
rails generate model Playergame game_id:primary_key player_id:primary_key team_id:integer player_first_name:string player_last_name:string player_position:integer player_uniform_number:integer field_goals_made:integer field_goals_att:integer field_goals_pct:float free_throws_made:integer free_throws_att:integer free_throws_pct:float three_point_field_goals_made:integer three_point_field_goals_att:integer three_point_field_goals_pct:float points:integer rebounds_total:integer rebounds_off:integer rebounds_def:integer assists:integer steals:integer blocked_shots:integer turnovers:integer personal_fouls:integer disqualifications:integer technical_fouls:integer minutes:integer ejections:integer starter:boolean
rails generate model Teamgame game_id:primary_key team_id:primary_key field_goals_made:integer field_goals_att:integer field_goals_pct:float free_throws_made:integer free_throws_att:integer free_throws_pct:float three_point_field_goals_made:integer three_point_field_goals_att:integer three_point_field_goals_pct:float points:integer rebounds_total:integer rebounds_off:integer rebounds_def:integer assists:integer steals:integer blocked_shots:integer turnovers:integer personal_fouls:integer technical_fouls:integer ejections:integer minutes:integer
But the Playergame model is a priority over the Teamgame model.
For the Player model, add player_position and player_uniform_number.
As I was working on the Draft 3.0 view in #26, I realized that we should use responsive bootstrap tables. http://getbootstrap.com/css/#tables-responsive So replace the player tables with responsive bootstrap tables as soon as #26 is finished. This will greatly improve the mobile UX for the tables.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.