---
title: "R Notebook"
output: html_notebook

---

# Data Visualization in ggplot

# Penn SAS Data Driven Discovery Summer Hangouts 2023

### Brynn Sherman (brynns@sas.upenn.edu)

### DDDI postdoctoral fellow | Department of Psychology

Load in the relevant packages

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

Check out the Iris dataset
```{r}
?iris
```

```{r}
iris
```
Plot sepal length and sepal width against one another
```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point()
```
Add a line of best fit

```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() + geom_smooth(method = "lm")
```
Let's separate out based on species 

First, by color:
```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) + geom_point() + geom_smooth(method = "lm")
```
Next, by facets

```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() + geom_smooth(method = "lm") + facet_wrap(~Species)
```
Note that by default, R has the scale of the three subplots as the same. How can we change that?
```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width)) + geom_point() + geom_smooth(method = "lm") + facet_wrap(~Species, scales = "free")
```
We can also change the shape of the points associated with the three species

```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, shape = Species)) + geom_point() + geom_smooth(method = "lm")
```
```{r}
ggplot(data = iris, aes(x = Sepal.Length, y = Sepal.Width, shape = Species)) + geom_point(alpha = .25) + geom_smooth(method = "lm")
```
Plotting the average petal length for each species

```{r}
groupedData = group_by(iris, Species) %>% summarise(meanPetalLength = mean(Petal.Length))
groupedData
```
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength)) + geom_bar(stat = "identity")
```
The bars represent the means, which isn't the most useful. Ideally, we'd also like a measure of variance.

One way to do this is to add error bars (in this case, standard error of the mean)

```{r}
groupedData = group_by(iris, Species) %>% summarise(meanPetalLength = mean(Petal.Length),sdPetalLength = sd(Petal.Length)/sqrt(n()))
groupedData
```
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength)) + geom_bar(stat = "identity") + geom_errorbar(data = groupedData,aes(x = Species, ymin = meanPetalLength - sdPetalLength, ymax = meanPetalLength + sdPetalLength))
```
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength)) + geom_bar(stat = "identity") + geom_errorbar(data = groupedData,aes(x = Species, ymin = meanPetalLength - sdPetalLength, ymax = meanPetalLength + sdPetalLength),width=.1)
```
Aside: Another way to plot the mean more directly (without creating a new dataframe)

```{r}
ggplot(data = iris,aes(x = Species, y = Petal.Length)) + geom_bar(stat = "summary", fun.y = "mean")
```


What if we want to get a better sense of the distribution of petal lengths for each species (not just the mean/sd)? 

Histograms
```{r}
ggplot(data = iris, aes(x = Petal.Length,fill = Species)) + geom_histogram()
```
```{r}
ggplot(data = iris, aes(x = Petal.Length)) + geom_histogram() + facet_wrap(~Species)
```

Boxplot
```{r}
ggplot(data = iris, aes(x = Species, y = Petal.Length)) + geom_boxplot() 
```
Dotplot
```{r}
ggplot(data = iris, aes(x = Species, y = Petal.Length)) + geom_dotplot(binaxis = "y",stackdir = "center")
```
```{r}
ggplot(data = iris, aes(x = Species, y = Petal.Length)) + geom_dotplot(binaxis = "y",stackdir = "center",dotsize=.5)
```
Violin plot
```{r}
ggplot(data = iris, aes(x = Species, y = Petal.Length)) + geom_violin()
```
Violin + boxplot

```{r}
ggplot(data = iris, aes(x = Species, y = Petal.Length)) + geom_violin() + geom_dotplot(binaxis = "y",stackdir = "center",dotsize=.5,alpha=.5)
```
Plotting the individual data points on the mean bars

```{r}
groupedData
```

```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5)
```
Now let's spruce up the graph

First fix the y axis label
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length')
```

Change the theme
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length') + theme_classic()
```

Color by species
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength, fill = Species)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length') + theme_classic()
```

Change the color scheme

```{r}
library(RColorBrewer)
```

```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength, fill = Species)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length') + theme_classic() + scale_fill_brewer(palette = "Accent")
```

Change the font, font size

```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength, fill = Species)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length') + theme_classic() + scale_fill_brewer(palette = "Accent") + theme(text = element_text(size = 20,family = "mono"))

# save the plot
ggsave('petal_means.pdf',width=5,height=5)
```
Change the size of the plot so that it's not cut off when it saves
```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength, fill = Species)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length') + theme_classic() + scale_fill_brewer(palette = "Accent") + theme(text = element_text(size = 20,family = "mono"))

# save the plot
ggsave('petal_means_wide.pdf',width=7,height=5)
```

Alternatively: is a legend really necessary in this plot?

```{r}
ggplot(data = groupedData,aes(x = Species, y = meanPetalLength, fill = Species)) + geom_bar(stat = "identity") + geom_dotplot(data = iris, aes(x = Species, y = Petal.Length), binaxis = "y", stackdir = "center",dotsize = .5) + ylab('Petal Length') + theme_classic() + scale_fill_brewer(palette = "Accent") + theme(text = element_text(size = 20,family = "mono")) + theme(legend.position = "none")

# save the plot
ggsave('petal_means_noLegend.pdf',width=5,height=5)
```
Load in a different dataset (mpg) to illustrate a few other specific instances that come up often
```{r}
?mpg
```

```{r}
mpg
```
How do highway and city mpg relate to one another, and is there an effect of the model year?
```{r}
ggplot(data = mpg,aes(x = cty, y = hwy, color = cyl)) + geom_point() + geom_smooth(method = "lm")
```
The above graph treats cylinder as a continuous variable (which is probably okay in this case). But what if it is discrete variable?
```{r}
ggplot(data = mpg,aes(x = cty, y = hwy, color = as.factor(cyl))) + geom_point() + geom_smooth(method = "lm")

# alternatively, could also change it within the dataframe:
# mpg$cyl = factor(mpg$cyl)
```
Changing it to a factor means that we get individual lines of best fit for each level of the variable. Here's a work-around to avoid that 
```{r}
ggplot(data = mpg,aes(x = cty, y = hwy)) + geom_point(aes(color = as.factor(cyl))) + geom_smooth(method = "lm")
```

```{r}
mpg
```
What is the average highway mpg by year for each manufacturer?

```{r}
groupedData = group_by(mpg, manufacturer, year) %>% summarise(meanMPG = mean(hwy),sdMPG = sd(hwy)/sqrt(n()))
groupedData
```
For the sake of space, let's only plot Audi, Chevy, Dodge, Ford, and Honda
```{r}
filteredData = filter(groupedData,manufacturer %in% c("audi","chevrolet","dodge","ford","honda"))
filteredData
```
```{r}
ggplot(data = filteredData,aes(x = manufacturer, y = meanMPG, fill = year)) + geom_bar(stat = "identity") + geom_errorbar(data = filteredData,aes(x = manufacturer, ymin = meanMPG - sdMPG, ymax = meanMPG + sdMPG),width=.5)
```
Unstack the bars
```{r}
ggplot(data = filteredData,aes(x = manufacturer, y = meanMPG, fill = year)) + geom_bar(stat = "identity", position = "dodge") + geom_errorbar(data = filteredData,aes(x = manufacturer, ymin = meanMPG - sdMPG, ymax = meanMPG + sdMPG),width=.5, position = position_dodge(.9))
```

Why did that not work?


```{r}
ggplot(data = filteredData,aes(x = manufacturer, y = meanMPG, fill = as.factor(year))) + geom_bar(stat = "identity", position = "dodge") + geom_errorbar(data = filteredData,aes(x = manufacturer, ymin = meanMPG - sdMPG, ymax = meanMPG + sdMPG),width=.5, position = position_dodge(.9))
```

Make generative art! Courtesy of https://r-graph-gallery.com/137-spring-shapes-data-art.html

```{r}
set.seed(567) # change this to generate slightly different images
ngroup=30
names=paste("G_",seq(1,ngroup),sep="")
DAT=data.frame()

for(i in seq(1:30)){
    data=data.frame( matrix(0, ngroup , 3))
    data[,1]=i
    data[,2]=sample(names, nrow(data))
    data[,3]=prop.table(sample( c(rep(0,100),c(1:ngroup)) ,nrow(data)))
    DAT=rbind(DAT,data)
    }
colnames(DAT)=c("Year","Group","Value")
DAT=DAT[order( DAT$Year, DAT$Group) , ]


coul = brewer.pal(12, "Paired") 
coul = colorRampPalette(coul)(ngroup)
coul=coul[sample(c(1:length(coul)) , size=length(coul) ) ]

ggplot(DAT, aes(x=Year, y=Value, fill=Group )) + 
    geom_area(alpha=1  )+
    theme_bw() +
    #scale_fill_brewer(colour="red", breaks=rev(levels(DAT$Group)))+
    scale_fill_manual(values = coul)+
     theme(
        text = element_blank(),
        line = element_blank(),
        title = element_blank(),
        legend.position="none",
        panel.border = element_blank(),
        panel.background = element_blank())
ggsave('generative_art.pdf',width=7,height=5)
```

