Tengo una matriz de expresiones genéticas versus células y me gustaría mostrarlas como un mapa de calor, lo que en sí mismo no es un problema. Sin embargo, mostrar todos los genes como yticklabels sería demasiado caótico y visualmente poco atractivo. Por lo tanto, anoté cada uno de los genes como pertenecientes a un grupo funcional en particular y me gustaría representar cada grupo funcional como un color y mostrar sus colores en el mapa de calor, en el mismo orden en que aparecen los genes. Solo para aclarar, no me gustaría agruparlos por colores, lo que creo que se podría hacer con el mapa de clúster seaborn.

Como tal, hasta ahora tengo un marco de datos de pandas que contiene un índice múltiple de genes y sus respectivos grupos funcionales y células.

He buscado mucho en Stackoverflow y Google para obtener respuestas, sin suerte. Este es mi primer intento de algo por el estilo, así que desafortunadamente no sé por dónde empezar exactamente.

Entonces, por simple simplicidad, digamos que tiene el siguiente marco de datos:

import seaborn as sns
import numpy as np
import pandas as pd

data=pd.DataFrame(np.array([(0,1,2),(4,5,6),(7,8,9)]), columns=['C1','C2','C3'], index=pd.MultiIndex.from_arrays([['Gene1','Gene2','Gene3'],['A','B','A']]))

Eso produciría lo siguiente:

           C1  C2  C3
Gene1   A   0   1   2
Gene2   B   4   5   6
Gene3   A   7   8   9

Ahora, simplemente puedo llamar a sns.heatmap(data) para generar el mapa de calor. Sin embargo, ¿cómo puedo personalizarlo para obtener colores que representen A y B en lugar de Gene1, Gene2, Gene3 como yticklabels? Por ejemplo, digamos que A es azul y B es verde, quiero que muestre las etiquetas ytick (de arriba a abajo) como azul, verde, azul.

Muchas gracias de antemano.

0
RDoc 1 jul. 2019 a las 15:04

1 respuesta

La mejor respuesta

Aquí hay una posible solución para crear nuevos ejes a la izquierda del mapa de calor, que muestra otro mapa de calor basado en los valores de los valores del segundo nivel Multiindex.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
import pandas as pd

data=pd.DataFrame(np.array([(0,1,2),(4,5,6),(7,8,9)]), 
                  columns=['C1','C2','C3'], 
                  index=pd.MultiIndex.from_arrays([['Gene1','Gene2','Gene3'],['A','B','A']]))


cats = data.index.to_frame().set_index(0)
u, inv = np.unique(cats.values, return_inverse=True)

colors = ["navy", "limegreen", "gold"]
assert(len(u) <= len(colors))

cmap = mcolors.ListedColormap(colors)
norm = mcolors.BoundaryNorm(np.arange(len(u)+1)-.5, len(u))

fig, (sax, hax) = plt.subplots(ncols=2, sharey=True,
                               gridspec_kw=dict(width_ratios=[1, data.shape[1]]))

im = sax.imshow(np.atleast_2d(inv).T, cmap=cmap, norm=norm)
hax.imshow(data.values, cmap="Greys")

sax.set_yticks(np.arange(len(cats)))
sax.set_yticklabels(cats.index)
sax.tick_params(bottom=False, labelbottom=False)

hax.set_xticks(np.arange(len(data.columns)))
hax.set_xticklabels(data.columns)

cbar = fig.colorbar(im, cax = fig.add_axes([.125, .08, .1, .04]), 
                    orientation="horizontal", ticks=np.arange(len(u)))
cbar.set_ticklabels(u)

plt.show()

enter image description here

1
ImportanceOfBeingErnest 4 jul. 2019 a las 12:16