---
title: "Data Visualization"
subtitle: "Visualizing 2D categorical and continuous by categorical, plus facets"
author: "Ron Yurko"
date: "06/04/2020"
---

```{r setup, echo = FALSE}
knitr::opts_chunk$set(fig.retina = 3, warning = FALSE, message = FALSE)
```

## Crimes against bar charts

.center[![](https://pbs.twimg.com/media/DiaDinUX0AQ2Hel?format=jpg&name=large)]

_Please do NOT never make something like this_...

---

## Revisiting MVP Mike Trout's batted balls in 2019

Created dataset of batted balls by the American League MVP Mike Trout in 2019 season using [`baseballr`](http://billpetti.github.io/baseballr/)

```{r load-trout, warning = FALSE, message = FALSE}
library(tidyverse)
trout_batted_balls <- 
  read_csv("http://www.stat.cmu.edu/cmsac/sure/materials/data/xy_examples/trout_2019_batted_balls.csv")
head(trout_batted_balls)
```

- each row / observation is a batted ball from Trout's 2019 season
- __Categorical__ / qualitative variables: `pitch_type`, `batted_ball_type`, `outcome`
- __Continuous__ / quantitative variables: `hit_x`, `hit_y`, `exit_velocity`, `launch_angle`

---

## First - more fun with [`forcats`](https://forcats.tidyverse.org/)

Variables of interest: [`pitch_type`](https://library.fangraphs.com/pitch-type-abbreviations-classifications/) and `batted_ball_type` - but how many levels does `pitch_type` have?

```{r pitch-type-table}
table(trout_batted_balls$pitch_type)
```

We can manually [`fct_recode`](https://forcats.tidyverse.org/reference/fct_recode.html) `pitch_type` (see [Chapter 15 of `R` for Data Science](https://r4ds.had.co.nz/factors.html) for more on factors)

```{r recode-pitch-type}
trout_batted_balls <- trout_batted_balls %>%
  filter(pitch_type != "null") %>% 
  mutate(pitch_type = fct_recode(pitch_type, "Changeup" = "CH", "Breaking ball" = "CU", #<<
                      "Fastball" = "FC", "Fastball" = "FF", "Fastball" = "FS",  "Fastball" = "FT", #<<
                      "Breaking ball" = "KC",  "Fastball" = "SI",  "Breaking ball" = "SL")) #<<
table(trout_batted_balls$pitch_type)
```


---

## 2D Categorical visualization (== more bar charts!)

.pull-left[

__Stacked__: a bar chart of _spine_ charts

```{r stacked-bars, fig.height=4}
trout_batted_balls %>%
  ggplot(aes(x = batted_ball_type,
             fill = pitch_type)) + #<<
  geom_bar() + theme_bw()
```


]
.pull-right[

__Side-by-Side__: a bar chart _of bar charts_

```{r side-by-side-bars, fig.height=4}
trout_batted_balls %>%
  ggplot(aes(x = batted_ball_type,
             fill = pitch_type)) + 
  geom_bar(position = "dodge") + theme_bw() #<<
```
]

---

## Which do you prefer?

.pull-left[

```{r ref.label='stacked-bars', fig.height=4, echo = FALSE}

```


]
.pull-right[

```{r, ref.label='side-by-side-bars', fig.height=4, echo = FALSE}

```
]

--


- Stacked bar charts emphasize __marginal__ distribution of `x` variable, 
  - e.g. $P$ (`batted_ball_type` = fly_ball)

- Side-by-side bar charts are useful to show the __conditional__ distribution of `fill` variable given `x`,
  - e.g. $P$ (`pitch_type` = Fastball | `batted_ball_type` = fly_ball)


---

## Brief review of joint, marginal, and conditional probabilities

__Joint distribution__: frequency of intersection, $P(X = x, Y = y)$

```{r joint-table}
library(gt)
trout_batted_balls %>%
  group_by(batted_ball_type, pitch_type) %>%
  summarize(joint_prob = n() / nrow(trout_batted_balls)) %>%
  pivot_wider(names_from = batted_ball_type, values_from = joint_prob) %>%
  gt()
```


--
__Marginal distribution__: row / column sums, e.g. $P(X = \text{popup}) = \sum_{y \in \text{pitch types}} P(X = \text{popup}, Y = y)$

--
__Conditional distribution__: probability event $X$ __given__ second event $Y$, 
- e.g. $P(X = \text{popup} | Y = \text{Fastball}) = \frac{P(X = \text{popup}, Y = \text{Fastball})}{P(Y = \text{Fastball})}$

---

## What about independence? Can we visualize it?

--
Two variables are __independent__ if knowing the level of one tells us nothing about the other
- i.e.  $P(X = x | Y = y) = P(X = x)$, and that $P(X = x, Y = y) = P(X = x) \times P(Y = y)$

--

.pull-left[

Create a __mosaic__ plot using [`vcd`](https://cran.r-project.org/web/packages/vcdExtra/vignettes/vcd-tutorial.pdf) package

```{r mosaic, eval = FALSE}
library(vcd)
mosaic(~ pitch_type + batted_ball_type, 
       data = trout_batted_balls)
```

- spine chart _of spine charts_

- height = marginal distribution of `pitch_type`

- width = conditional distribution of `batted_ball_type` | `pitch_type`

- area = joint distribution

__[`ggmosaic`](https://github.com/haleyjeppson/ggmosaic) has issues...__
]
.pull-right[
```{r ref.label = 'mosaic', echo = FALSE, fig.height=6}

```
]

---

## Continuous by categorical: side-by-side and color

.pull-left[

```{r violin-box, eval = FALSE}
trout_batted_balls %>%
  ggplot(aes(x = pitch_type, #<<
             y = exit_velocity)) +
  geom_violin() +
  geom_boxplot(width = .2) +
  theme_bw()
```

```{r ref.label = 'violin-box', echo = FALSE, fig.height=4}
```
  
]
.pull-right[
```{r ecdf, eval = FALSE}
trout_batted_balls %>%
  ggplot(aes(x = exit_velocity,
             color = pitch_type)) + #<<
  stat_ecdf() + 
  theme_bw() +
  theme(legend.position = "bottom")
```

```{r ref.label = 'ecdf', echo = FALSE, fig.height=4}
```
]

---

## What about for histograms? 

.pull-left[

```{r stacked-hist, eval = FALSE}
trout_batted_balls %>%
  ggplot(aes(x = exit_velocity,
             fill = pitch_type)) + #<<
  geom_histogram() +
  theme_bw() +
  theme(legend.position = "bottom")
```

```{r ref.label = 'stacked-hist', echo = FALSE, fig.height=4}
```
  
]
.pull-right[
```{r freq-poly, eval = FALSE}
trout_batted_balls %>%
  ggplot(aes(x = exit_velocity,
             color = pitch_type)) + #<<
  geom_freqpoly() +
  theme_bw() +
  theme(legend.position = "bottom")
```

```{r ref.label = 'freq-poly', echo = FALSE, fig.height=4}
```
]

---

## We can always facet instead...

.pull-left[

```{r facet-hist-wrap, eval = FALSE}
trout_batted_balls %>%
  ggplot(aes(x = exit_velocity)) + 
  geom_histogram() +
  theme_bw() +
  facet_wrap(~ pitch_type, ncol = 2) #<<
```

```{r ref.label = 'facet-hist-wrap', echo = FALSE, fig.height=4}
```
  
]
.pull-right[
```{r facet-hist-grid, eval = FALSE}
trout_batted_balls %>%
  ggplot(aes(x = exit_velocity)) + 
  geom_histogram() +
  theme_bw() +
  facet_grid(pitch_type ~., margins = TRUE) #<<
```

```{r ref.label = 'facet-hist-grid', echo = FALSE, fig.height=4}
```
]

---

## Facets make it easy to move beyond 2D

```{r stacked-bars-facet, fig.width=12, fig.height=5, fig.align='center'}
trout_batted_balls %>%
  ggplot(aes(x = pitch_type,
             fill = batted_ball_type)) + 
  geom_bar() + theme_bw() +
  facet_wrap(~ outcome, ncol = 5) +
  theme(legend.position = "bottom")
```




