On April 2nd, 2013 Yu Darvish flirted with pitching perfection. To demonstrate his ability to deceive batters with a consistent delivery over different pitch types, redditor DShep created this gif, which layers video of five different pitches thrown by Darvish on April 24th:

We can easily recreate pitch trajectories with publicly available PITCHf/x data using the pitchRx R package. First, we collect all the pitches thrown by Darvish to Albert Pujols on April 24th:

dat <- scrape(start = "2013-04-24", end = "2013-04-24")
atbats <- subset(dat$atbat, pitcher_name == "Yu Darvish" & 
                batter_name == "Albert Pujols")
pitches <- plyr::join(atbats, dat$pitch, by = c("num", "url"))

The pitchRx package also provides a function called animateFX() which makes it easy to animate pitches. Note that we take a different perspective from above by imagining the pitches coming closer as time progresses. If you’re following along, you probably want to do animation::saveHTML(animateFX(pitches)) instead for a better viewing experience. You can also check out this post to see how to make more interactive animations.


One thing to notice here is the different release points by Darvish (especially for his slider). Furthermore, Darvish didn’t even throw a curveball to Pujols. If you look closer at the original gif, you can actually see a different batter (than Pujols) in the batter’s box (look for a white bat). Darvish’s delivery looks very similar on videotape, but his arm angle (and thus) release point might be slightly different across pitch types according to the PITCHf/x data. Let’s take a closer look at Darvish’s release point during this start.

atbats <- subset(dat$atbat, pitcher_name == "Yu Darvish")
Darvish <- plyr::join(atbats, dat$pitch, by = c("num", "url"))
qplot(data=Darvish, x=as.numeric(x0), y=as.numeric(z0), color=pitch_type) +
plot of chunk release

As you can see, Darvish has quite different release points according to pitch type. For example, his slider tends to be more ‘side-arm’ compared to his four-seam fastball. Now, whether that difference is distinguishable to the human-eye is another question…

EDIT: Thanks to a recommendation by @Sky_Kalman, normalizing release points should make it easier to make visual comparison of flight paths across the pitch types. Here is one way to go about that:

pitches$x0 <- mean(as.numeric(pitches$x0))
pitches$z0 <- mean(as.numeric(pitches$z0))