---
title: "QC Dashboard"
output: 
  flexdashboard::flex_dashboard:
    orientation: rows
    vertical_layout: scroll
    theme: bootstrap
editor_options: 
  chunk_output_type: console
params:
  prefix: files.idepth
  nClusters: 3
  GMKey: NULL 
---

```{r setup, include=FALSE}
suppressMessages(library(flexdashboard))
suppressMessages(library(tidyverse))
suppressMessages(library(plotly))
suppressMessages(library(ape))
suppressMessages(library(reshape2))
suppressMessages(library(ggtree))
suppressMessages(library(ggmap))

prefix <- params$prefix

set.colors <- c('#1f78b4','#33a02c','#6a3d9a','#a6cee3','#b2df8a','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6')

```


Individuals
===================================== 

Row
-----------------------------------------------------------------------

```{r numsnps}
#fai file for getting genome length
fai_path <- paste0(prefix, ".fna.fai")
df_fai <- read.table(fai_path, header = F)
genome_size <- sum(df_fai$V2)

#summary of the unfiltered FCT
sum_path <- paste0(prefix, ".FILTER.summary")
df_sum <- read.table(sum_path, header =T)

#total number of SNPs found by pipeline
first_line <- df_sum %>% filter(FILTER == ".")
snps_remain <- first_line[1,2]
snps_remain.m <- round(snps_remain / 1000000,1)

#how many SNPs got filtered
other_lines <- df_sum %>% 
  filter(FILTER!=".") %>% 
  summarise(sum_snps = sum(N_VARIANTS))
fil_snps <- other_lines[1,1]  
tot_snps <- snps_remain + fil_snps

proj_name <- basename(prefix)

#num SNPs in pruned data
nums.nps <- nrow(read.table(paste0(prefix, ".bim"), header = T))

#estimate watterson's theta:
num.samples <- nrow(read.table(paste0(prefix, ".idepth"), header = T))

#harmonic number calculation for n-1 chromosomes (2*sample size)
Hn = 0
N = num.samples * 2
for (i in 1:(N-1)) {
  Hn = Hn + 1.0/i
}

#theta as num. (snps / harmonic number) / sequence length
w_theta <- round((snps_remain/(Hn)) / genome_size, 3) * 100
```


### Individuals
```{r}
valueBox(num.samples, icon = "fa-check-double")
```

### Mil. SNPs

```{r}
valueBox(snps_remain.m, icon = "fa-dna")
```

### Estimated diversity

```{r}
#div_text <- paste0(round((div_est*100),2),"%")
div_text <- paste0(w_theta, "%")
valueBox(div_text, icon = "fa-dna")
```


### Mean depth

```{r}
mean.depth <- round(mean(read.table(paste0(prefix, ".idepth"), header = T)$MEAN_DEPTH), 1)
valueBox(mean.depth, icon = "fa-align-center")
```

Column {.sidebar}
-----------------------------------------------------------------------
### About

This is an individual quality control report generated snpArcher for the dataset `r proj_name`. In total, `r tot_snps` SNPs were discovered before any filters were applied. The GATK best practices filters were then applied to this dataset and `r fil_snps` were removed, leaving `r snps_remain`. The approximate nucleotide diversity in the sample using the Watterson estimator is `r w_theta `%. For the purposes of this report, we apply several sensible filters including removing all indels, non-biallelic SNPs, SNPs with a minor allele frequency < 0.01, SNPs with >75% missing data, and samples with <2x sequencing depth. We then randomly selected SNPs within a set window size to end up with approximately 100k SNPs (in this report, `r nums.nps`). These are effectively an LD pruned set of SNPs. All analyses in this report are based on this set of 100k SNPs. **This should not be considered a final analyses and are solely intended to direct quality control of the dataset. **

Row 
-----------------------------------------------------------------------

```{r}
#Column {.sidebar}
#-----------------------------------------------------------------------
#shiny sider bar
#sliderInput('clusters', 'Cluster count', 3,
#              min = 1, max = 6)

input <- list()
input$clusters <- params$nClusters
input$GMKey <- params$GMKey

```

### Genomic PCA

```{r, fig.width = 6, fig.height = 8}
# PCA plot --------------------------------------------------------------
pca.path <- paste0(prefix, ".eigenvec")
#this makes it reasonably robust to running with plink 1.9 or plink 2.0
tmp.head <- sub("#", "", readLines(pca.path))
df.pca <- read.table(text = tmp.head, header = TRUE)
df.val <- read.table(gsub("vec","val", pca.path), header = FALSE)
df.val$prop <- (df.val$V1 / (sum(df.val$V1))) * 100
df.val$PC <- paste0("PC", row.names(df.val))

#add depth
depth.path <- paste0(prefix, ".idepth")
df.depth <- read.table(depth.path, header = T)
df.depth <- df.depth %>%  mutate_if(is.numeric, round, digits = 2)

df.pca <- left_join(df.pca, df.depth, by = c("IID" = "INDV"))

set.seed(42)
k <- kmeans(df.pca[,c("PC1","PC2")], input$clusters, nstart = 25, iter.max = 100)
df.pca$cluster <- paste("cluster",k$cluster, sep = "_")


##PCA plot
(ggplot(data = df.pca, aes(x = PC1, y = PC2, text = IID, fill = cluster), color = "grey90") + 
  geom_point(alpha = 0.9, shape = 21, size = 3) + 
  theme_bw() +
  theme(text = element_text(size = 14),
        legend.position = "none") +
  xlab(paste0("PC1", ": ", round(df.val[1,2],1),"% variance")) +
  ylab(paste0("PC2", ": ", round(df.val[2,2],1),"% variance")) +
  scale_fill_manual(values = set.colors)) %>% 
  ggplotly(tooltip=c("text","x","y")) 

```

> Fig. 1: The first step is to run a principal component analysis of the genotypes to identify broad clustering patterns in the data. In order to aid the visualization of sample groupings throughout the document, a k-means clustering of 3 is applied. This means that throughout the document the three colors in each plot refer to the three clusters identified in the genomic PCA. This is a good first pass to look for outlier samples, which may either be problematic or interesting samples. The following analyses help to distinguish among these possibilities. **Note these 3 clusters may or may not have any meaningful biological relevance!**.

### Depth and PC Correlation

```{r, fig.width = 4, fig.height = 8}


#pivot longer so we can plot as a facet
df.pca.long <- df.pca %>% 
  select(-cluster, -N_SITES) %>% 
  pivot_longer(cols = -c("IID", "MEAN_DEPTH"), names_to = "PC") %>% 
  mutate(PC = factor(PC, levels = c("PC1", "PC2", "PC3", "PC4", "PC5",
                                    "PC6", "PC7", "PC8", "PC9", "PC10")))

#get % var expl
df.pca.long <- left_join(df.pca.long, df.val, by = "PC")

df.pca.long <- df.pca.long %>% 
  mutate(PC.lab = paste0(PC, " (" , round(prop,0),"%)"),
         order = as.numeric(gsub("PC","",PC)),
         PC.lab = factor(PC.lab))

df.pca.long$PC.lab <- reorder(df.pca.long$PC.lab, df.pca.long$order)

#it is easier to visualize just 6 PCs, rather than all 10
df.pca.long <- df.pca.long %>% filter(PC %in% c("PC1", "PC2", "PC3", "PC4", "PC5", "PC6")) 

df.r2 <- df.pca.long %>% 
  group_by(PC.lab) %>% 
  nest() %>% #create a tibble of dataframes
  mutate(Mod = map(data, ~lm(MEAN_DEPTH ~ value, data = .x))) %>% #add model result to the dataframe as a list
  mutate(R2 = map_dbl(Mod, ~round(summary(.x)$r.squared, 2))) #extract R2 from the model

df.r2 <- df.r2 %>% 
  select(PC.lab, R2) %>% 
  as.data.frame()

(df.pca.long %>% 
  ggplot() + 
    geom_point(aes(x = value, y = MEAN_DEPTH, text = IID)) +
    facet_wrap(~ PC.lab, ncol = 3) +
    geom_text(data = df.r2, aes(x = 0, y = 1,
              label = paste("R2 = ", R2, sep = " ")),
              color = "blue", size = 3) +
    theme_bw() +
    theme(axis.text.x = element_text(angle = 90)) +
    labs(x = NULL, y = "SNP Depth")) %>% 
  ggplotly(tooltip = c("text", "x", "y"))
```

> Fig. 2: Sometimes if there are batch effects, the PCA groups will correlate with sequencing depth, which may indicate there is some technical signal in the data. An R2 value (depth ~ PC) is shown for each component and a large value here may suggest there is a technical signal in the data. The percent variance explained by each PC is also shown as the amount of variance explained by one PC out of 10 total PCs.

Row 
-----------------------------------------------------------------------

### SNP Depth

```{r, fig.width = 5, fig.height = 5}
# depth plot --------------------------------------------------------------
#depth is read in the PCA chunk
imiss.path <- paste0(prefix, ".imiss")
df.imiss <- read.table(imiss.path, header =T)

df.depth.miss <- inner_join(df.depth, df.imiss, by = "INDV")
df.depth.miss <- df.depth.miss %>% 
 mutate_if(is.numeric, round, digits = 5)

#replace df.pca with clusters() for shiny
#r.missing <- reactive(
  df.depth.miss <- left_join(df.depth.miss, df.pca[,c("IID","cluster")], by = c("INDV" = "IID"))
#)

#replace df.depth.miis with r.missing for shiny
#renderPlotly(
  #need to wrap ggplot in () to pipe to plotly
  (ggplot(data = df.depth.miss, aes(text = INDV)) +
    geom_point(aes(x = MEAN_DEPTH, y = F_MISS, fill = cluster), 
               size = 3, color = "black") +
    theme_bw() +
    theme(legend.position = "none") + 
    scale_fill_manual(values = set.colors)+ 
    labs(x = "SNP Depth", y = "Missingness")) %>% 
    ggplotly(tooltip=c("text","x","y"))
#)

```

> Fig. 3: There is typically a relationship between how much missing data there is and total sequencing depth. Use this plot to identify a potential cutoff for how strictly you want to filter your individuals by sequencing depth and/or individuals. For example, one might remove individuals with a sequencing depth < 4 if the rate of missingness per SNP is higher than seems reasonable. 

### Mapping rate


```{r, fig.width = 5, fig.height = 5}
# bamstat plot --------------------------------------------------------------
bamstat.path <- paste0(prefix, "_bam_sumstats.txt")

# Check if the bamstat file exists
if (file.exists(bamstat.path)) {
  # Read the BAM stats file
  df.bamstat <- read.table(bamstat.path, header = TRUE)

  # Perform the inner join with df.depth.miss
  df.depth.miss.bamstat <- inner_join(df.depth.miss, df.bamstat, by = c("INDV" = "Sample"))
  df.depth.miss.bamstat <- df.depth.miss.bamstat %>% 
    mutate_if(is.numeric, round, digits = 5)

  # Plot the results if the BAM stats file is available
  ggplotly(
    ggplot(data = df.depth.miss.bamstat, aes(text = INDV)) +
      geom_point(aes(x = Percent_mapped, y = MEAN_DEPTH, fill = cluster), 
                 size = 3, color = "black") +
      theme_bw() +
      theme(legend.position = "none") + 
      scale_fill_manual(values = set.colors) + 
      labs(x = "% Reads Mapped", y = "SNP Depth") +
      xlim(0, 100),
    tooltip = c("text", "x", "y")
  )
} else {

  message("BAM stats file not found, skipping BAM stats plot.")
}
```


> Fig. 4: The percent of reads mapped is calcuated from the mapping rate to the reference genome. A lower mapping rate may indicate there are contaminants in your reads or the sample is from the wrong species. For example, a mapping rate <80% means either the sample is of the wrong species (so many reads did not map) or 20% sample comes from another species (such as bacterial contamination). 

### Heterozygosity

```{r, fig.width = 5, fig.height = 5}
het.path <- paste0(prefix, ".het")
df.het <- read.table(het.path, header =T)

df.het <- left_join(df.het, df.pca, by = c("INDV" = "IID"))

(ggplot(data = df.het, aes(x = PC1, y = F, text = INDV, color = cluster)) + 
  geom_point() +
    labs(y = "F (inbreeding coefficient)", x = "PC1") +
    theme_bw() +
    theme(legend.position = "none") +
        scale_color_manual(values = set.colors)) %>% ggplotly()

```

> Fig. 5: The inbreeding coefficient is an estimate of excess homozygosity or heterozygosity. Values close to +1 indicate extensive homozygosity in the sample and values close to -1 indicate excess in heterozygotes. Check for samples that are outliers in the PCA plot that have very negative F values, as these could indicate cross contamination among samples.

```{r, fig.width = 10, fig.height = 5, include = F, eval = F}
##this was per site heterozygosity and it was not that informative so it has been commented out

#het.path <- paste0(prefix, ".hwe")
#df.het <- read.table(het.path, header =T)
#
#biggest_chr <- df.het %>% group_by(CHR) %>% 
#  summarise(max_pos = max(POS)) %>% 
#  arrange(-max_pos) %>% 
#  slice_max(max_pos)
#
#df.het <- df.het %>% 
#  separate(OBS.HOM1.HET.HOM2., into = c(NA,"het",NA), sep = "/") %>% 
#  mutate(het = as.numeric(het))
#
#library(zoo)
#df.het.fil  <-  df.het %>% filter(CHR == biggest_chr$CHR) 
#df.het.fil$het.roll <- zoo::rollmean(df.het.fil$het, 100, fill = NA)
#
#(ggplot(data = df.het.fil) + 
#  geom_point(aes(x = POS/1000000, y = het.roll)) +
#  labs(y = "Rolling mean number of heterozygous sites", x = paste("Position (Mbp) on ", biggest_chr$CHR)) +
#  theme_bw()) %>% ggplotly()
#
```

Row 
-----------------------------------------------------------------------

### Tree 

```{r, fig.height=12, fig.width=12}

dist.id <- read.table(paste0(prefix, ".dist.id"))["V2"]
dist.id <- left_join(dist.id, df.pca[,c("IID","cluster")], by = c("V2" = "IID"))

df.dist <- read.table(paste0(prefix, ".dist"))

mat.dist <- as.dist(df.dist)

nj.dist <- ape::nj(mat.dist)
nj.dist$tip.label <- dist.id$V2

mycol <- set.colors[factor(dist.id$cluster)]

#a messy ape plot
#plot(nj.dist, tip.color = mycol, type = "unrooted", use.edge.length	= F)

# ggtree
p.ggtree <- ggtree(nj.dist, layout="daylight", branch.length = "none")

## with ggtree labeling scheme
# p.ggtreelabs <- p.ggtree %<+% dist.id + 
#   geom_tiplab(pch = 5, aes(col = cluster)) +
#   theme(legend.position = "none") +
#   scale_color_manual(values = set.colors) 

## this tree doesnt work well because the edges get cut off
## due to different axes units in the tree vs text
## ggplot2::xlim(-500, 500) + ylim(-500, 500) sort of helps
# p.ggtreelabs

metat <- p.ggtree$data %>%
  dplyr::inner_join(dist.id, c('label' = 'V2'))

#hacky solution to add text labels
#using the ggtree label geoms is not supported by plotly
p.ggtree.custom <- p.ggtree +
  geom_text(data = metat,
             aes(x = x,
                 y = y,
                 colour = cluster,
                 label = label), size = 3) +
  theme(legend.position = "none") +
  scale_color_manual(values = set.colors) 

p.ggtree.custom

# This interactive code really should work but when rendered with plotly, but in the pipeline, the tree is blank
# this isnt an issue with local install so it may be a ggtree version issue

#ggplotly(p.ggtree.custom, tooltip=c("label", "cluster"))

```

> Fig. 6: A very simple neighbor joining tree is built from a simple distance matrix among all samples in the dataset. The leaves are colored by the clusters identified in the PCA. 

Row
-----------------------------------------------------------------------

### Relatedness matrix

```{r,  fig.height=10, fig.width=6}

df.rel <- read.table(paste0(prefix, ".king"))
colnames(df.rel) <- dist.id$V2
rownames(df.rel) <- dist.id$V2

mat.rel <- as.matrix(df.rel)

#check for -Inf in the matrix
l.inf <- grep("-Inf", mat.rel, value = T)

#clustering will fail if there are -Inf
if(length(l.inf)==0){

  # Run clustering
  rel.dendro <- as.dendrogram(hclust(d = dist(x = mat.rel)))
  sample.order <- order.dendrogram(rel.dendro)
  #we could also plot the dendrogram, but it is potentially confusing
  #with the already plotted NJ tree
  
  #pivot does not seem to work with matrices, so reverting to melt from reshape2
  df.rel.long <- melt(as.matrix(df.rel))
  names(df.rel.long) <- c("Sample1", "Sample2", "relatedness")
  
  matrix.names <- row.names(mat.rel)
  
  df.rel.long$Sample2 <- factor(x = df.rel.long$Sample2,
                                 levels = matrix.names[sample.order], 
                                 ordered = TRUE)
  
  df.rel.long$Sample1 <- factor(x = df.rel.long$Sample1,
                                 levels = matrix.names[sample.order], 
                                 ordered = TRUE)
  
  pl.1 <- (ggplot(data = df.rel.long, aes(x=Sample1, y=Sample2, fill=relatedness)) + 
    geom_tile() +
    theme(
      axis.text.x = element_text(angle = 90),
      axis.title = element_blank(),
      axis.text = element_text(size = 5),
      legend.position = "top"
    ) +
     scale_fill_gradient2(low = "blue", high = "red", mid = "white",
                          midpoint = mean(df.rel.long$relatedness),  
                          name="relatedness")) %>% 
    ggplotly(tooltip=c("relatedness","x","y"))
  
  pl.1

}else{
  print("too little data (SNPs or Individuals) to cluster relatedness matrix")
}

```

> Fig. 7: We build a king relatedness matrix using Plink to evaluate if there are closely related samples. Samples with a relatedness of 0.5 indicate they are identical, values close to 0.25 indicate parent-child or sibling relatedness, and second degree relatedness are ~0.125. You may want to remove samples with > 0.354 if you want to remove very closely related sample which can bias population genomic estimates. 

Row
-----------------------------------------------------------------------

### Map

```{r, fig.width = 10, fig.height = 10}

if((file.exists(paste0(prefix, ".coords.txt"))) & (file.size(paste0(prefix, ".coords.txt"))>0)){
    df.coords <- read.table(paste0(prefix, ".coords.txt"))
    names(df.coords) <- c("sample.ID","long","lat")
    
    if(max(df.coords$lat < 90) & min(df.coords$lat) > 0 
           & max(df.coords$long < -35) & min(df.coords$long > -180)){
      map_type = "north america"
    } else { map_type = "world"}
    
    g <- list(
      scope = map_type,
      showland = TRUE,
      landcolor = toRGB("grey83"),
      subunitcolor = toRGB("white"),
      countrycolor = toRGB("white"),
      showlakes = TRUE,
      lakecolor = toRGB("white"),
      showsubunits = TRUE,
      showcountries = TRUE,
      resolution = 50,
      #center = list( #not sure why, but centering on a coordinates does not work (just defaults to middle of full projection)
      #  lat = 33.94423,
      #  lon = -119.3048))
      projection = list(
        type = 'conic conformal',
        rotation = list(lon = -100)),
      lonaxis = list(
       showgrid = TRUE,
       gridwidth = 0.5,
       range = c(min(df.coords$long) - 1, max(df.coords$long) + 1),
       dtick = 5
     ),
     lataxis = list(
       showgrid = TRUE,
       gridwidth = 0.5,
       range = c(min(df.coords$lat) -1, max(df.coords$lat) +1),
       dtick = 5
     )
   )
   
    df.coords <- left_join(df.pca, df.coords, by = c("IID" = "sample.ID"))
      
    df.coords$color <- set.colors[factor(dist.id$cluster)]
    
    mycol <- set.colors[factor(df.coords$cluster)]
    
    df.coords$long.jit <- jitter(as.numeric(df.coords$long), 4)
    df.coords$lat.jit <- jitter(as.numeric(df.coords$lat), 4)
    
    plot_geo(df.coords, lat = ~lat.jit, lon = ~long.jit) %>% 
      layout(legend = list(orientation = 'h'), geo = g) %>% 
      add_markers(
        text = ~paste(IID, cluster, PC1, PC2, sep = "<br />"),
        color = ~cluster, symbol = I("circle"), size = I(60), 
        hoverinfo = "text", colors = set.colors[1:input$clusters],
      ) %>% 
     colorbar(title = "cluster")   
  }else{
    print("a map will appear here if you includes a .coords file ")
}

```

> Fig. 8: Here, an interactive map is produced if there is a coordinate file available with latitude and longitude in decimal degrees. See the project README for how to setup this file for analysis. 

Row
-----------------------------------------------------------------------

### Terrain Map

```{r, fig.width = 10, fig.height = 10}

if(file.exists(paste0(prefix, ".coords.txt"))){
  if(!is.null(input$GMKey)){
    df.coords <- read.table(paste0(prefix, ".coords.txt"), na.strings = c("", "nan"))
    names(df.coords) <- c("sample.ID","long","lat")
    
    df.coords <- left_join(df.pca, df.coords, by = c("IID" = "sample.ID"))

    df.coords <- df.coords %>% filter(!is.na(long))
    num.missing <- df.coords %>% filter(is.na(long)) %>% nrow() 

    df.coords$color <- set.colors[factor(df.coords$cluster)]
    
    mycol <- set.colors[factor(df.coords$cluster)]
    
    #jitter points
    df.coords$Longitude <- jitter(as.numeric(df.coords$long), 8)
    df.coords$Latitude <- jitter(as.numeric(df.coords$lat), 8)

    register_google(key = input$GMKey)

    us <- c(left = -125, bottom = 25.75, right = -67, top = 49)

    cal.map <- get_googlemap("California", zoom = 6, maptype = "terrain", scale = 4, size = c(640, 640))

    terrain.map <- cal.map %>% 
      ggmap() + 
        geom_point(data = df.coords, aes(x = Longitude, y = Latitude,
                   color = cluster, size = 2.5, label = IID), alpha = 0.8) +
        theme_bw() + 
        labs(x = NULL, y = NULL) +
      scale_color_manual(values = set.colors) +
      theme(legend.position = "none")

    ggplotly(terrain.map, tooltip=c("IID","Longitude", "Latitude"))
  
  }else{
    print("a terrain map will appear here if you provide a google API key in the config file") 
  }
 
}else{
  print("a map will appear here if you includes a .coords file ")
}

```

> Fig. 9: Here, a terrain map is produced using the google maps API

Row
-----------------------------------------------------------------------

### Admixture

```{r, width = 10, height = 5}
  # admixture ---------------------------------------------------------------

k2 <- paste0(prefix, ".2.Q")
k3 <- paste0(prefix, ".3.Q")
samps <- paste0(prefix, ".fam")

x <- read.table(k2, header = F)

struct_files <- c(k2,k3)
cat_admx <- do.call("rbind",lapply(struct_files,
                               FUN=function(files){
                                 x <- read.table(files, header = F)
                                 names(x) <- gsub("V", "pop", names(x)) #rename ancestral pops
                                 x.samps <- read.table(samps) %>% select(V2) #get sample names from .fam file
                                 x$sampleID <- x.samps$V2 #add sample name to df
                                 x$k <- gsub(".Q","",substr(files, nchar(files)-3+1, nchar(files)))
                                 x.long <- x %>% #pivot longer 
                                   pivot_longer(names_to = "popGroup", values_to = "prob", cols = -c(sampleID, k))
                                 x.long
                               }))

cat_admx.wide <- cat_admx %>% 
  filter(k == 2) %>% 
  select(sampleID, k, popGroup, prob) %>% 
  pivot_wider(names_from = "popGroup", values_from = "prob") %>% 
  arrange(pop1, pop2) %>% 
  mutate(sample_order = 1:n()) %>% 
  ungroup()
sample.order <- cat_admx.wide %>% select(sampleID, sample_order)
cat_admx <- left_join(cat_admx, sample.order, by = c("sampleID"))


##############################

p.k23 <- cat_admx %>% 
  filter(k == 2 | k == 3) %>% 
  ggplot(aes(x = fct_reorder(sampleID, sample_order), y = prob, fill = factor(popGroup), text = sampleID)) +
  geom_col(aes(fill = factor(popGroup)), size = 0.1) +
  facet_grid(rows = vars(k), switch = "x", scales = "free", space = "free") +
  theme_minimal() +
  labs(x = NULL, y = "Ancestry") +
  scale_y_continuous(expand = c(0, 0)) +
  scale_x_discrete(expand = expansion(add = 1)) +
  theme(
    panel.spacing.x = unit(0.0, "lines"),
    axis.text.x = element_text(angle = 90, size = 6),
    panel.grid = element_blank(),
    strip.text.x = element_text(angle = 90, size = 6),
    legend.position = "none"
  ) +
  #scale_fill_manual(name = "grp",values = c("#1b9e77","#d95f02","#7570b3"), guide = F) +xlab(NULL)  + theme(legend.position = "none")
  scale_fill_manual(name = "grp",values = c("#fb8072","#80b1d3","#8dd3c7"), guide = F) +xlab(NULL)  + theme(legend.position = "none")


#make admix interactive
pl.admix <- ggplotly(p.k23, tooltip=c("text", "y"))
pl.admix
```

> Fig. 10: Admixture was run on the dataset for k = 2 and k = 3. These are arbitrarily selected and no cross validation is done. Because these groupings are made seperate from the clusters in the PCA, they are colored by the admixture assignments and not the PCA groupings. 

Row
-----------------------------------------------------------------------

`Generated by snpArcher`
