Раскраска дендограмм по группам - PullRequest
3 голосов
/ 25 мая 2020

Я создал тепловую карту на основе корреляционной матрицы Спирмена, используя карту кластеров морского дна, как показано ниже: Я хочу нарисовать дендрограмму. Я хочу, чтобы дендрограмма выглядела так: дендрограмма но на тепловой карте

Я создал список цветов, как показано ниже, и получил сообщение об ошибке:

def assign_tree_colour(name,val_dict,coding_names_df):
ret = None
if val_dict.get(name, '') == 'Group 1':
    ret = "(0,0.9,0.4)"   #green
elif val_dict.get(name, '') == 'Group 2':
    ret = "(0.6,0.1,0)"   #red
elif val_dict.get(name, '') == 'Group 3':
    ret = "(0.3,0.8,1)"   #light blue
elif val_dict.get(name, '') == 'Group 4':
    ret = "(0.4,0.1,1)"   #purple
elif val_dict.get(name, '') == 'Group 5':
    ret = "(1,0.9,0.1)"   #yellow
elif val_dict.get(name, '') == 'Group 6':
    ret = "(0,0,0)"   #black
else:
    ret = "(0,0,0)"         #black
return ret

def fix_string(str):
    return str.replace('"', '')

external_data3 = [list(z) for z in coding_names_df.values]
external_data3 = {fix_string(z[0]): z[3] for z in external_data3}

tree_label = list(df.index)
tree_label = [fix_string(x) for x in tree_label]
tree_labels = { j : tree_label[j] for j in range(0, len(tree_label) ) }

tree_colour = [assign_tree_colour(label, external_data3, coding_names_df) for label in tree_labels]
tree_colors = { i : tree_colour[i] for i in range(0, len(tree_colour) ) }


sns.set(color_codes=True)
sns.set(font_scale=1)
g = sns.clustermap(df, cmap="bwr",
                   vmin=-1, vmax=1,
                   yticklabels=1, xticklabels=1,
                   cbar_kws={"ticks":[-1,-0.5,0,0.5,1]},
                   figsize=(13,13),
                   row_colors=row_colors,
                   col_colors=col_colors,
                   method='average',
                   metric='correlation',
                   tree_kws=dict(colors=tree_colors))
g.ax_heatmap.set_xlabel('Genus')
g.ax_heatmap.set_ylabel('Genus')
for label in Group.unique():
    g.ax_col_dendrogram.bar(0, 0, color=lut[label],
                            label=label, linewidth=0)
g.ax_col_dendrogram.legend(loc=9, ncol=7, bbox_to_anchor=(0.26, 0., 0.5, 1.5))
ax=g.ax_heatmap



 File "<ipython-input-64-4bc6be89afe3>", line 11, in <module>
tree_kws=dict(colors=tree_colors))



File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\matrix.py", line 1391, in clustermap
    tree_kws=tree_kws, **kwargs)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\matrix.py", line 1208, in plot
    tree_kws=tree_kws)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\matrix.py", line 1054, in plot_dendrograms
    tree_kws=tree_kws

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\matrix.py", line 776, in dendrogram
    return plotter.plot(ax=ax, tree_kws=tree_kws)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\seaborn\matrix.py", line 692, in plot
    **tree_kws)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\collections.py", line 1316, in __init__
    colors = mcolors.to_rgba_array(colors)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\colors.py", line 294, in to_rgba_array
    result[i] = to_rgba(cc, alpha)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\colors.py", line 177, in to_rgba
    rgba = _to_rgba_no_colorcycle(c, alpha)

  File "C:\Users\rotemb\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\colors.py", line 240, in _to_rgba_no_colorcycle
    raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))

ValueError: Invalid RGBA argument: 0

Любая помощь на это был бы очень признателен! Тнх!

Ответы [ 2 ]

2 голосов
/ 25 мая 2020

Согласно документации sns.clustermap, цвет дендрограммы может быть установлен с помощью tree_kws (принимает dict) и его атрибута colors, который ожидает список кортежей RGB, например (0.5, 0.5, 1). Также кажется, что colors не поддерживает ничего, кроме данных формата кортежа RGB.

Заметили ли вы, что clustermap поддерживает вложенные списки или фреймы данных для иерархических цветовых полос между дендрограммами и корреляционной матрицей? Они могут быть полезны, если дендрограммы становятся слишком переполненными.

Надеюсь, это поможет!

Редактировать

Список RGB - это последовательность строки цвета в LineCollection - он использует последовательность, как это aws каждая строка в обеих дендрограммах. (Порядок кажется, что порядок начинается с самой правой ветви дендрограммы столбца) Чтобы связать определенную метку с точкой данных, вам необходимо выяснить порядок рисования точек данных в дендрограммах.

Редактировать II

Вот минимальный пример раскраски дерева на основе sns.clustermap примеров:

import matplotlib.pyplot as plt
import seaborn as sns; sns.set(color_codes=True)
import pandas as pd


iris = sns.load_dataset("iris")
species = iris.pop("species")
g = sns.clustermap(iris)
lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)
# For demonstrating the hierarchical sidebar coloring
df_colors = pd.DataFrame(data={'r': row_colors[row_colors == 'r'], 'g': row_colors[row_colors == 'g'], 'b': row_colors[row_colors == 'b']}) 
# Simple class RGBA colormap
colmap = {'setosa': (1, 0, 0, 0.7), 'virginica': (0, 1, 0, 0.7), 'versicolor': (0, 0, 1, 0.7)}
g = sns.clustermap(iris, row_colors=df_colors, tree_kws={'colors':[colmap[s] for s in species]})
plt.savefig('clustermap.png')

clustermap.png Как видите , порядок нарисованных линий дерева начинается с правого верхнего угла изображения, таким образом, он не привязан к порядку точек данных, отображаемых в таблице кластеров. С другой стороны, для этой цели можно использовать цветные полосы (управляемые атрибутами {row,col}_colors).

0 голосов
/ 20 августа 2020

Основываясь на приведенном выше ответе, вот пример, раскрашивающий три основных ветки по-разному, методом грубой силы (первые 49 строк красным, следующие 35 строк зеленым и последние 62 строки синим, оставшиеся две строки черным) :

import matplotlib.pyplot as plt
import seaborn as sns; sns.set(color_codes=True)
import pandas as pd


iris = sns.load_dataset("iris")
species = iris.pop("species")
g = sns.clustermap(iris)
lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)
# For demonstrating the hierarchical sidebar coloring
df_colors = pd.DataFrame(data={'r': row_colors[row_colors == 'r'], 'g': row_colors[row_colors == 'g'], 'b': row_colors[row_colors == 'b']}) 
# Simple class RGBA colormap
colmap = {'setosa': (1, 0, 0, 0.7), 'virginica': (0, 1, 0, 0.7), 'versicolor': (0, 0, 1, 0.7)}
g = sns.clustermap(iris, row_colors=df_colors, tree_kws={'colors':[(1,0,0,1)]*49+[(0,1,0,1)]*35+[(0,0,1,1)]*63+[(0,0,0,1)]*2})
plt.savefig('clustermap.png')

scipy формат связи ):

n_leaves = len(g.dendrogram_row.linkage)+1
n0_ndx = len(g.dendrogram_row.linkage) - 1
n1_ndx = int(g.dendrogram_row.linkage[n0_ndx][0])-n_leaves
n2_ndx = int(g.dendrogram_row.linkage[n0_ndx][1])-n_leaves
n21_ndx = int(g.dendrogram_row.linkage[n2_ndx][0])-n_leaves
n22_ndx = int(g.dendrogram_row.linkage[n2_ndx][1])-n_leaves

n1 = int(g.dendrogram_row.linkage[n1_ndx][3])-1
n21 = int(g.dendrogram_row.linkage[n21_ndx][3])-1
n22 = int(g.dendrogram_row.linkage[n22_ndx][3])-1

g = sns.clustermap(iris, row_colors=df_colors, tree_kws={'colors':[(1,0,0,1)]*n1+[(0,1,0,1)]*n21+[(0,0,1,1)]*n22+[(0,0,0,1)]*(n_leave\
s-1-n1-n21-n22)})

Хотя, я не придумал, как по-другому раскрасить верхнюю дендрограмму .. .

...