# How to Distinguish 22 Variables in a Stacked Bar Graph?

I have a tabular dataset that contains 75 samples (rows) and measures of 22 different human cell types (columns), like the following:

# pandas dataframe:
df = pd.DataFrame(np.random.rand(75, 22), columns=
['B cells naive','B cells memory','Plasma cells','T cells CD8','T cells CD4 naive','T cells CD4 memory resting','T cells CD4 memory activated','T cells follicular helper','T cells regulatory (Tregs)','T cells gamma delta','NK cells resting','NK cells activated','Monocytes','Macrophages M0','Macrophages M1','Macrophages M2','Dendritic cells resting','Dendritic cells activated','Mast cells resting','Mast cells activated','Eosinophils','Neutrophils'])


I want to visualize how much of each of the 22 cell types present in the 75 samples. So I thought to use a stacked bar graph where each bar represent a sample and the stacks show the estimated number of each cell type found in the sample. Here is the graph:

Problem: the cell types represented in the stacked bar graph do not have unique and distingishable color. For example, there are three cell types have the the same color (red) and this makes the graph pointless because we can not visualize the frequency of each cell types per sample.

Question: what are some possible ways to distinguish the cell types for each sample? ... Any ideas what sets of colors and/or patterns could be used to solve this problem?

Do you think there are other ways to visualize, other than a stacked bar graph?

Thanks!

• Do you want the plot to help yourself understand what's going on, or to present to others (eg, in a paper or a talk) to communicate some point about the data? – gung - Reinstate Monica Nov 2 '16 at 2:40
• Primarily, I want to plot the data to make sense of it. @gung – MEhsan Nov 2 '16 at 2:59

Maybe try the gradient style harvey balls approach https://stackoverflow.com/questions/22225086/harvey-balls-in-r

It at least would show all the observations and all the cells types. I could imagine also using size of the circle to show the count of observed cell types.

That eliminates the inability to distinguish strongly between 22 different colors.

• Never seen this before. Interesting. – shadowtalker Nov 2 '16 at 18:16

The questions to me include not only what to show but in what sense this could ever work.

I am no biologist and at most recognise some of the names here (but couldn't explain them to pass a Biology 100 quiz). I have no idea what amounts would make sense in any examples whatsoever.

Graphically I suggest that

1. If you have a big enough monitor and/or can print this out at say A0 size, the problem is easier, but we can here post only pictures of modest size.

2. If you can cheat by leaving out half of the sample identifiers, then we can too.

3. It's a lousy program that does not allow 22 different colours, but I see no point to such a scheme, unless there is some rationale to it, say a hierarchical scheme, e.g. that one group of "similar" types is a series of slightly different reds, another a series of slightly different blues.

4. I'd expect a multivariate analysis, e.g. a correspondence analysis, to yield a seriation of rows and columns and/or plots in different spaces to identify groups, outliers, and so forth.

This is my one suggestion, a two-way bar chart or table plot in which all the work is done by row and column labels, except that as above in #3 and #4 it could surely be improved by having good data and thinking about groups of types and getting a better ordering of rows and columns. The values here are pure random garbage. As your own example is random too, I imagine no gain in learning enough Pandas to use it.

Instead of displaying all 22 cell types equally, you might be better off taking advantage of the known hierarchy of relations among these different types of blood cells.

Start with the major distinction between lymphoid (B cells, T cells, NK cells, plasma cells) and myeloid (monocytes, macrophages, eosinophils, neutrophils) lineages, each presented separately with a break between them in the column for each sample. For example, myeloid on top, then a break, then lymphoid on the bottom of each column. In that case there should be no confusion if you use the same color once each within the myeloid and lymphoid lineages. Sublineages within each major lineage can then be distinguished by color, with different shades of a single color representing different levels of differentiation or activation within the sublineage (e.g., naive B cells, memory B cells, plasma cells going from pink to red).

Comparisons among samples might be easier if you first did some clustering of the samples based on their relative cell-type compositions and then ordered the samples according to their clusters.

Mapping the data for each sample onto a 2-dimensional display based on the lineage differentiation hierarchy as in this image might be even more useful than your column-based display. Circles of different sizes could be used to distinguish absolute or relative numbers of each type of cell in the 2-D hierarchy display.

How about putting the cell types, rather than the samples, on the x-axis?

 import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.melt(pd.DataFrame(np.random.rand(75, 22), columns=
['B cells naive','B cells memory','Plasma cells','T cells CD8','T cells CD4 naive','T cells CD4 memory resting','T cells CD4 memory activated','T cells follicular helper','T cells regulatory (Tregs)','T cells gamma delta','NK cells resting','NK cells activated','Monocytes','Macrophages M0','Macrophages M1','Macrophages M2','Dendritic cells resting','Dendritic cells activated','Mast cells resting','Mast cells activated','Eosinophils','Neutrophils']))

g = sns.factorplot(data = df, aspect = 2, kind = "strip",
x = "variable",
y = "value", color = "black")
plt.xticks(rotation = 90)
g.savefig("/tmp/out.png")


This plot doesn't let you see how the different cell types are associated with each other per sample, but hey, no one plot can do everything.