Advertisement
matthewrmata

Release Point Heat Maps

Jun 3rd, 2015
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
R 4.38 KB | None | 0 0
  1. ##################################
  2. # Release_Point_Heat_Home_Away.r #
  3. ##################################
  4.  
  5. # This program plots a series of heat maps of the data at a number of
  6. # distances in the range of a pitcher's release point.
  7. # These images are saved as jpeg's and can be converted into a GIF.
  8.  
  9. # Written by Matthew Mata, May 2015 (matthewrmata@gmail.com)
  10.  
  11. #############
  12. # LIBRARIES #
  13. #############
  14.  
  15. # This library calls MySQL
  16. library('RODBC');
  17. library('calibrate');
  18. library('diagram');
  19. library('fields');
  20.  
  21. #############
  22. # FUNCTIONS #
  23. #############
  24.  
  25. # This function creates a heat map a various distances for the release point
  26. heat_track <- function(Pitch,FIRST,LAST,YEAR,H_or_A){
  27.     x0 <- Pitch$x0;
  28.     y0 <- Pitch$y0;
  29.     z0 <- Pitch$z0;
  30.     vx0 <- Pitch$vx0;
  31.     vy0 <- Pitch$vy0;
  32.     vz0 <- Pitch$vz0;
  33.     ax <- Pitch$ax;
  34.     ay <- Pitch$ay;
  35.     az <- Pitch$az;
  36.     N_p <- length(x0);
  37.     # Define the function with compact support
  38.     Patch <- array(0,c(50,50));
  39.     dx <- 0.005;
  40.     for (i in 1:50){
  41.         x <- dx*(i-0.5) - 0.125;
  42.         for (j in 1:50){
  43.             y <- dx*(j-0.5) - 0.125;
  44.             r <- sqrt(x**2 + y**2);
  45.             if (r <= 0.125){
  46.                 Patch[i,j] <- 1.0;
  47.             }
  48.             else {
  49.                 Patch[i,j] <- 0;
  50.             }
  51.         }
  52.     }
  53.     # Set the number of increments
  54.     N_y <- 30;
  55.     # Initialize the arrays for storing the data at different distances
  56.     R_x <- array(0,dim=c(N_y,N_p));
  57.     R_y <- array(0,dim=c(N_y,N_p));
  58.     R_z <- array(0,dim=c(N_y,N_p));
  59.     # Set the interval of where the release point will occur
  60.     D_y <- seq(50,179/3,length=N_y);
  61.     a <- 0.5*ay;
  62.     b <- vy0;
  63.     # Loop over the distances
  64.     for (i in 1:N_y){
  65.         # Set the coefficients for use in the Pythagorean theorem to solve a t^2 + b t + c = (Distance in y) for t
  66.         c <- y0 - D_y[i];
  67.         t <- (-b - sqrt(b^2 - 4*a*c))/(2*a);
  68.         # Evaluate the distance at t
  69.         R_x[i,] <- t(0.5*ax*t^2 + vx0*t + x0);
  70.         R_y[i,] <- t(0.5*ay*t^2 + vy0*t + y0);
  71.         R_z[i,] <- t(0.5*az*t^2 + vz0*t + z0);
  72.     }
  73.     # Set bounds for the plot (adjusted to two decimal places)
  74.     min_x <- floor(100*min(c(R_x)))/100 - 0.25;
  75.     max_x <- ceiling(100*max(c(R_x)))/100 + 0.25;
  76.     min_z <- floor(100*min(c(R_z)))/100 - 0.25;
  77.     max_z <- ceiling(100*max(c(R_z)))/100 + 0.25;
  78.     L_x <- round((max_x - min_x)/0.005,digits=0) + 1;
  79.     L_z <- round((max_z - min_z)/0.005,digits=0) + 1;
  80.     X <- seq(min_x+dx/2,max_x-dx/2,length=L_x);
  81.     Y <- seq(min_z-dx/2,max_z-dx/2,length=L_z);
  82.     Heat_Array <- array(0,dim=c(L_x,L_z));
  83.     for (i in 1:N_y){
  84.         # Set the file name
  85.         if (i < 10){
  86.             filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_0",i,".jpg",sep="");
  87.         }
  88.         else {
  89.             filename <- paste(LAST,"_",YEAR,"_RP_",H_or_A,"_",i,".jpg",sep="");
  90.         }
  91.         jpeg(filename);
  92.         # Zero out the array
  93.         Heat_Array <- 0*Heat_Array;
  94.         # Construct the heat map
  95.         for (j in 1:N_p){
  96.             x_ind <- floor((R_x[i,j]-min_x)/dx) + 1;
  97.             y_ind <- floor((R_z[i,j]-min_z)/dx) + 1;
  98.             x_patch_range <- seq(x_ind-24,x_ind+25,length = 50);
  99.             y_patch_range <- seq(y_ind-24,y_ind+25,length = 50);
  100.             Heat_Array[x_patch_range,y_patch_range] <- Heat_Array[x_patch_range,y_patch_range] + Patch;
  101.         }
  102.         Heat_Array <- Heat_Array/max(c(Heat_Array));
  103.         # Plot
  104.         image.plot(X,Y,Heat_Array,xlim=c(min_x,max_x),ylim =c(min_z,max_z), col = tim.colors(64), zlim=c(0,1),
  105.                 xlab='Horizontal Location (Feet)',ylab='Vertical Location (Feet)',
  106.                 main=paste(FIRST," ",LAST," 20",YEAR," (",H_or_A,") at ",round(D_y[i],digits=2)," Ft",sep=""));
  107.         dev.off();
  108.     }
  109. }
  110.  
  111. ########
  112. # MAIN #
  113. ########
  114.  
  115. # Set the player name (PARAMETER)
  116. FIRST <- 'Felix';
  117. LAST <- 'Hernandez';
  118. YEAR <- 14;
  119.  
  120. DB <- paste("MLB20",YEAR,sep="");
  121.  
  122. # Set HA to "1" for Home and "2" for Away data
  123. HA <- 1;
  124.  
  125. if (HA == 1) {H_or_A <- 'H'} else {H_or_A <- 'A'};
  126.  
  127. print(paste("Pitcher: ",FIRST," ",LAST,", 20",YEAR," (",H_or_A,")",sep=""));
  128.  
  129. # Set the channel
  130. channel <- odbcConnect(DB);
  131.  
  132. # Set the query to get the PITCHf/x data and exclude any missing entries (by finding entries missing the px value)
  133. # Also exclude intentional balls
  134. Release_Query = paste("SELECT x0, y0, z0, vx0, vy0, vz0, ax, ay, az FROM pitches WHERE
  135.                       ab_id IN (SELECT ab_id FROM atbats WHERE
  136.                        pitcher = (SELECT eliasid FROM players WHERE first = '",
  137.                        FIRST,"' AND last = '",LAST,"') AND half = ",HA,") AND
  138.                        pitch_type <> 'IN' AND px IS NOT NULL",sep="");
  139.  
  140. # Download the pitch data
  141. Release <- sqlQuery(channel,Release_Query);
  142.  
  143. # Close the channel
  144. close(channel);
  145.  
  146. heat_track(Release,FIRST,LAST,YEAR,H_or_A);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement