---
title: "ggplot2 examples"
author: "Kith Pradhan"
date: "2024-05-14"
output: 
  slidy_presentation: 
  #html_document:
  #  toc: true
  #  toc_float: true
  #  code_folding: hide
---

## A Basic Scatter Plot with geom_point

The first example will use the builtin `mtcars` dataset to show off a simple scatterplot.

```{r}
library("tidyverse")

#this library makes the output look a little better
#if it's not installed yet call
#install.packages("pander")
library("pander")

#load the data
data(mtcars)

#look at the first few rows
#mtcars %>% head() %>% pander()

#here's another way to do it
pander(head(mtcars))


```

Let's look at the relationship between *mpg* and *hp* with a simple scatterplot using [geom_point()](https://ggplot2.tidyverse.org/reference/geom_point.html).

Remember these three key points to using ggplot2.

1. the data
2. the geom
3. the mapping from data to geom.

```{r}
ggplot(mtcars, aes(x=mpg, y=hp)) +
    geom_point()


```

### aesthetics

We can assign variables to be visualized through the geom's features. In the code below, the *gear* of the car is shown off as color. *gear* is being treated as a `r class(mtcars$gear)` and ranges over `r length(unique(mtcars$gear))` distinct values.

```{r}
ggplot(mtcars, aes(x=mpg, y=hp, color=gear)) +
    geom_point()


```

By default, *gear* is stored as a floating point number. If you change its class to a factor, ggplot will treat it as a categorical variable, and assign attributes based on a discrete scale rather than continuous.

```{r}

#turn gear into a factor
mtcars$gear2 = as.factor(mtcars$gear)
#Here's another way to do it
mtcars <- mtcars %>% mutate(gear2 = as.factor(gear))

pander(head(mtcars))
ggplot(mtcars, aes(x=mpg, y=hp, color=gear2)) +
    geom_point()

```

## Displaying Heatmaps with geom_tile

In these examples we'll be using the builtin *starwars* dataset to show off how to make a heatmap in ggplot2. If you've made heatmaps in base R with the *image()* function, you're already familiar with how to display data in matrix form. This is a very intuitive way to handle 2D data.

ggplot2 uses a different way to handle 2D data for heatmaps. Here, we treat each individual heatmap tile as a separate observation. Instead of a rectangular matrix with *nSubjects* rows and *nVariables* columns, we need to make a new data structure that has *nSubjects* \* *nVariables* rows, with one or more columns to distinguish the variables and their values.

Luckily for us, there is a *tidyverse* function called [unnest()](https://tidyr.tidyverse.org/reference/unnest.html) that can rearrange the data for us automatically.

For the first example, let's look at the films that each character had an appearance in using [geom_tile()](https://ggplot2.tidyverse.org/reference/geom_tile.html)

```{r}

data("starwars")
head(starwars$name)
head(starwars$films)

#This is the original form of the data
starwars %>% select(name, films) %>% head() %>% pander()

#this is how it needs to be to use ggplot's heatmap
starwars_films <- starwars %>% select(name, films) %>% unnest(films)
starwars_films %>% head(30) %>% pander()


#now show the heatmap
ggplot(starwars_films, aes(x=films, y=name)) +
    geom_tile()

```

Let's look at another heatmap. The types of starships piloted by each character, broken down by the pilot's species. Here, we're rearranging the necessary info into a tiled data structure, then we're adding extra info from the original data with [left_join()](https://dplyr.tidyverse.org/reference/mutate-joins.html)

```{r}


#make a new data.frame that has the info we want to visualize
starwars_ships <- starwars %>% select(name, starships) %>% unnest(starships)
pander(starwars_ships) 


#add info from the original data.frame to the new data.frame
starwars_shipsSpecies <- left_join(starwars_ships, select(starwars, name, species), by="name")
pander(starwars_shipsSpecies)

#color the heatmap elements by species
ggplot(starwars_shipsSpecies, aes(x=starships, y=name, fill=species)) +
    geom_tile() + 
    theme(axis.text.x = element_text(angle = 90))



```

## Exploring the Olympics Dataset

Here are a few more ggplot2 examples using the olympics dataset.\
We'll be looking for associations between the number/type of medals won and other interesting variables.

```{r, cache=T}

events <- read_csv("athlete_events.csv")


```

This dataset contains `r nrow(events)` rows and `r ncol(events)` columns. To make things more manageable, we'll be restricting our exploration to only the most popular games and teams.

## Question 1 (review)

How do you find the sports & teams with the largest number of players?

```{r}

#sports with the most number of players
events  %>% count(Sport) %>% arrange(desc(n)) %>% top_n(n=10, wt=n) 

#from here you can extract the names from the Sport column
top_sports <- events  %>% 
  count(Sport) %>% 
  arrange(desc(n)) %>% 
  top_n(n=10, wt=n) %>%
  pull(Sport)

top_sports

#another way to do it
top_sports <- names(tail(sort(table(events$Sport)), 10))
top_teams <- names(tail(sort(table(events$Team)), 10))

top_sports
top_teams

```

## Question 2 (review)

Let's also restrict ourselves to only using the players that won a medal. We want the players that won a medal in any of the top sports from any of the top teams. How do you set up this smaller dataset?

```{r}
events_top <- events %>% 
    filter(!is.na(Medal )) %>%
    filter(Sport %in% top_sports, Team %in% top_teams)

events_top
```

## Question 3

Which team had the most number of medals? Show the results in a bar graph using [geom_col](https://ggplot2.tidyverse.org/reference/geom_bar.html).

```{r}

pander(count(events_top, Team, Medal))

#bar plot of number of medals by team
count(events_top, Team, Medal) %>%
    ggplot(aes(x=Team, y=n, fill=Medal)) +
        geom_col()

#stack them side by side
count(events_top, Team, Medal) %>%
    ggplot(aes(x=Team, y=n, fill=Medal)) +
        geom_col(position="dodge")

#let's change the colors
count(events_top, Team, Medal) %>%
    ggplot(aes(x=Team, y=n, fill=Medal)) +
        geom_col(position="dodge") + 
        scale_fill_manual(values = c(
            "Gold" = "gold", 
            "Bronze" = "goldenrod", 
            "Silver" = "gray"))

#what if you want to order the teams by the total number of medals?
count(events_top, Team, Medal) %>%
    ggplot(aes(x=fct_rev(fct_reorder(Team, n)), y=n, fill=Medal)) +
        geom_col(position="dodge") + 
        scale_fill_manual(values = c(
            "Gold" = "gold", 
            "Bronze" = "goldenrod", 
            "Silver" = "gray"))


#Change the order, gold-silver-bronze
events_top$Medal <- factor(events_top$Medal, levels=c("Gold", "Silver", "Bronze"))
count(events_top, Team, Medal) %>%
    ggplot(aes(x=fct_rev(fct_reorder(Team, n)), y=n, fill=Medal)) +
        geom_col(position="dodge") + 
        scale_fill_manual(values = c(
            "Gold" = "gold", 
            "Bronze" = "goldenrod", 
            "Silver" = "gray")) +
        theme(axis.text.x = element_text(angle = 90)) +
        labs(x="Teams", y="Medal Count")


```

## Question 4

Look at the total number of medals over the years for each team. Do you notice any weird patterns?
Can you correct them?

```{r}
#total number of medals over the years
events_top %>% count(Team, Year) 


#look at the number of medals by team and year
events_top %>% 
    count(Team, Year) %>% 
    ggplot(aes(x=Year, y=n, color=Team)) +
        geom_point() +
        geom_line()

#another way to look at the number of medals by team and year
events_top %>% 
    count(Team, Year) %>% 
    ggplot(aes(x=Year, y=n, color=Team)) +
        geom_point() +
        geom_line() +
        facet_wrap(~Team)

```

The spiky pattern in the number of medals won through the years is because many of the top sports only exist in the summer olympics. Inconsistencies like are very hard to spot if you're only reading the numbers instead of visualizing them.\
Let's see what it looks like if we restrict ourselves to the summer games.

```{r}
#total number of medals over the years
events_top %>% 
    filter(Season == "Summer") %>%
    count(Team, Year) 


#look at the number of medals by team and year
events_top %>% 
    filter(Season == "Summer") %>%
    count(Team, Year) %>% 
    ggplot(aes(x=Year, y=n, color=Team)) +
        geom_point() +
        geom_line() +
        facet_wrap(~Team)
```

## Question 5

Do you see any patterns in the weights of medal winning participants over the years? Show the weight distributions with [geom_histogram](https://ggplot2.tidyverse.org/reference/geom_histogram.html) and [geom_density_ridges](https://wilkelab.org/ggridges/reference/geom_density_ridges.html)

```{r, message=F}

#distribution of weights by medal
ggplot(events_top, aes(x=Weight)) + geom_histogram()
ggplot(events_top, aes(x=Weight, fill=Sex)) + geom_histogram()
ggplot(events_top, aes(x=Weight, fill=Sex)) + geom_histogram() + facet_wrap(~Year)

```

[ggridges](https://cran.r-project.org/web/packages/ggridges/vignettes/introduction.html) is another very useful package for displaying multiple histograms. It's not part of tidyverse, but can be installed very easily and uses the standard ggplot2 calling form. Be sure to specify a **categorical** variable to the *group* aesthetic if you want to visualize distinct ridges.

```{r, cache=T, fig.height=12, fig.width=8, message=F, cache=T}
#if it's not installed yet.
#install.packages("ggridges")
library("ggridges")

ggplot(events_top, aes(x=Weight, group=Year, y=Year)) + 
  geom_density_ridges() + 
  facet_wrap(~Sex, ncol=2)


#separate it by sport
ggplot(events_top, aes(x=Weight, group=Year, y=Year, fill=Sex)) + 
  geom_density_ridges() + 
  facet_wrap(Sport~Sex, ncol=4)

```
