<p>Your cluster labels come from graph clustering implemented in the <code>FindClusters()</code> function. The resulting clusters are then visualised with a 2D tSNE plot (via <code>RunTSNE()</code> and <code>TSNEPlot()</code>). So, your cluster 13 is not split into three sub-clusters but cells within cluster 13 <strong><em>look</em></strong> somewhat <strong><em>distant</em></strong> from each other on the tSNE plot. Having mentioned distances on a tSNE plot, please see this SE Data Science entry <a href="https://datascience.stackexchange.com/a/10820">Can closer points be considered more similar in T-SNE visualization?</a> and especially the comment <strong><em>"What I mean is that you can't just use distance in the lower space as a similarity criterion"</em></strong>. In your case "the lower space" would be your tSNE plot.</p>

<p>As far as I can see from your code, you are following the widely-adopted "Seurat workflow" and all seem fine including your TSNE plot output. I could not spot the QC step though: apart from the one at object initiation, one usually applies filters for number of genes and % mitochondrial gene contribution (using <code>FilterCells()</code> in Seurat v2 and <code>subset()</code> in Seurat v3).</p>

<p>It would be a good idea to try UMAP instead of tSNE, please see <a href="https://www.biorxiv.org/content/10.1101/298430v1" rel="nofollow noreferrer">Evaluation of UMAP as an alternative to t-SNE for single-cell data (Becht et al, 2019)</a>. Seurat v3 vignettes are now using UMAP and not tSNE any more.</p>

<p>Lastly, please see <a href="https://distill.pub/2016/misread-tsne/" rel="nofollow noreferrer">How to Use t-SNE Effectively</a> to learn about points to take into account when using/interpreting tSNE plots. You will see that you would get surprisingly dissimilar tSNE plots from the same underlying data with different parameters (some are hardcoded in the <code>RunTSNE()</code> function).</p>

CC BY-SA 4.0
2019-08-22T18:23:24.370Z
Yes, I was missing step where I needed to filter for mitochondria and number of genes.
user2998764
CC BY-SA 4.0
2019-08-23T09:22:07.460Z
Great and very comprehensive answer!
jxx_fa
CC BY-SA 4.0
2019-08-23T09:44:16.347Z
Hi user2998764, I was just curious, do the tSNE plot looks "better" after the QC for % mito and genes?
haci
CC BY-SA 4.0
2019-08-22T13:03:43.063Z
2019-08-22T13:03:43.063Z
haci
<p>I am running a single cell dataset (count data - exon) through Seurat. After running tsne I see a cluster (13) split in 3 different locations on the plot. Here are the commands I am running:</p>

<pre><code>library('Seurat')
## rows (genes) that have 99% zeros were filtered out, 
## and then columns (cells) that have 99% zeros were filtered out
isp.data &lt;- read.table(file = "genes.cells99.percent.filtered", sep = 
            ",", row.names = 1, header=TRUE)
isp &lt;- CreateSeuratObject(raw.data = isp.data, project = 
       "brain_regions")
isp &lt;- NormalizeData(object = isp, normalization.method = 
       "LogNormalize",scale.factor = 10000)
isp &lt;- FindVariableGenes(object = isp, mean.function = ExpMean, 
       dispersion.function = LogVMR,do.plot = FALSE)
hv.genes &lt;- head(rownames(isp@hvg.info), 1000)
isp &lt;- ScaleData(object = isp, genes.use = hv.genes, num.cores = 3)
isp &lt;- RunPCA(object = isp, pc.genes = hv.genes, pcs.compute = 100, 
       do.print = TRUE, pcs.print = 1:5, genes.print = 5)
PCElbowPlot(object = isp, num.pc = 100)
isp &lt;- JackStraw(object = isp, num.replicate = 100, display.progress = 
                 FALSE, num.pc = 30)
JackStrawPlot(object = isp, PCs = 1:30)
isp &lt;- FindClusters(object = isp, reduction.type = "pca", dims.use = 
        1:26, resolution= 0.75, print.output = 0, save.SNN = TRUE, 
        force.recalc=TRUE)
isp &lt;- RunTSNE(isp, dims.use = 1:26, do.fast = T)
TSNEPlot(isp, do.label = T, pt.size = 0.5)
</code></pre>

<p>Here is the tsne plot:</p>

<p><a href="https://i.sstatic.net/oOIg7.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/oOIg7.png" alt="enter image description here"></a></p>

<p>I have tried varying parameters for resolution in FindClusters (from 0.5-3.5), but that just increases the clusters found. Further I tried to play around with parameters min.dist (0.75,1), n_neighbors (10 to 30) and perplexity(5 to 50) but I still get at least 1-2 clusters split in the tsne plot.</p>

<p>Another thing I have tried is to reduce the dimension (dims.use=10) on which tsne is ran but the clusters seem to be too close together, like so:</p>

<p><a href="https://i.sstatic.net/JhQWH.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/JhQWH.png" alt="dims_reduced"></a></p>

<p>Note: Dimensionality of dataset (after filtering) - 23824 genes across 8967 samples.</p>

<p>My question being why does such behavior happen? Is my filtering strategy not correct? Have I not normalized/scaled data correctly? </p>

<rna-seq><seurat><single-cell><clustering><normalization>
Cluster is split in 2-3 locations on tsne plot - Suerat
# Cluster is split in 2-3 locations on tsne plot - Suerat

(Asked by: username_0 on 2019-07-11)

I am running a single cell dataset (count data - exon) through Seurat. After running tsne I see a cluster (13) split in 3 different locations on the plot. Here are the commands I am running:
library('Seurat')
## rows (genes) that have 99% zeros were filtered out, 
## and then columns (cells) that have 99% zeros were filtered out
isp.data <- read.table(file = "genes.cells99.percent.filtered", sep = 
            ",", row.names = 1, header=TRUE)
isp <- CreateSeuratObject(raw.data = isp.data, project = 
       "brain_regions")
isp <- NormalizeData(object = isp, normalization.method = 
       "LogNormalize",scale.factor = 10000)
isp <- FindVariableGenes(object = isp, mean.function = ExpMean, 
       dispersion.function = LogVMR,do.plot = FALSE)
hv.genes <- head(rownames(isp@hvg.info), 1000)
isp <- ScaleData(object = isp, genes.use = hv.genes, num.cores = 3)
isp <- RunPCA(object = isp, pc.genes = hv.genes, pcs.compute = 100, 
       do.print = TRUE, pcs.print = 1:5, genes.print = 5)
PCElbowPlot(object = isp, num.pc = 100)
isp <- JackStraw(object = isp, num.replicate = 100, display.progress = 
                 FALSE, num.pc = 30)
JackStrawPlot(object = isp, PCs = 1:30)
isp <- FindClusters(object = isp, reduction.type = "pca", dims.use = 
        1:26, resolution= 0.75, print.output = 0, save.SNN = TRUE, 
        force.recalc=TRUE)
isp <- RunTSNE(isp, dims.use = 1:26, do.fast = T)
TSNEPlot(isp, do.label = T, pt.size = 0.5)

Here is the tsne plot:

I have tried varying parameters for resolution in FindClusters (from 0.5-3.5), but that just increases the clusters found. Further I tried to play around with parameters min.dist (0.75,1), n_neighbors (10 to 30) and perplexity(5 to 50) but I still get at least 1-2 clusters split in the tsne plot.
Another thing I have tried is to reduce the dimension (dims.use=10) on which tsne is ran but the clusters seem to be too close together, like so:

Note: Dimensionality of dataset (after filtering) - 23824 genes across 8967 samples.
My question being why does such behavior happen? Is my filtering strategy not correct? Have I not normalized/scaled data correctly?

**Tags:** rna-seq, seurat, single-cell, clustering, normalization

---

## 1 answers

### Answer by username_1 on 2019-08-22. Score: 3 | Accepted answer

Your cluster labels come from graph clustering implemented in the `FindClusters()` function. The resulting clusters are then visualised with a 2D tSNE plot (via `RunTSNE()` and `TSNEPlot()`). So, your cluster 13 is not split into three sub-clusters but cells within cluster 13 ***look*** somewhat ***distant*** from each other on the tSNE plot. Having mentioned distances on a tSNE plot, please see this SE Data Science entry [Can closer points be considered more similar in T-SNE visualization?](https://datascience.stackexchange.com/a/10820) and especially the comment ***"What I mean is that you can't just use distance in the lower space as a similarity criterion"***. In your case "the lower space" would be your tSNE plot.

As far as I can see from your code, you are following the widely-adopted "Seurat workflow" and all seem fine including your TSNE plot output. I could not spot the QC step though: apart from the one at object initiation, one usually applies filters for number of genes and % mitochondrial gene contribution (using `FilterCells()` in Seurat v2 and `subset()` in Seurat v3).

It would be a good idea to try UMAP instead of tSNE, please see [Evaluation of UMAP as an alternative to t-SNE for single-cell data (Becht et al, 2019)](https://www.biorxiv.org/content/10.1101/298430v1). Seurat v3 vignettes are now using UMAP and not tSNE any more.

Lastly, please see [How to Use t-SNE Effectively](https://distill.pub/2016/misread-tsne/) to learn about points to take into account when using/interpreting tSNE plots. You will see that you would get surprisingly dissimilar tSNE plots from the same underlying data with different parameters (some are hardcoded in the `RunTSNE()` function).

> **Comments:**
> **username_0**: Yes, I was missing step where I needed to filter for mitochondria and number of genes.  
> **username_2**: Great and very comprehensive answer!  
> **username_1**: Hi user2998764, I was just curious, do the tSNE plot looks "better" after the QC for % mito and genes?  

---

