Как выразить классы на оси тепловой карты в Seaborn

Я создал очень простую тепловую карту с Seaborn, отображающую квадратную матрицу подобия. Вот одна строка кода, которую я использовал:

sns.heatmap(sim_mat, linewidths=0, square=True, robust=True)
sns.plt.show()

и вот результат, который я получаю:

введите описание изображения здесь

Что я хотел бы сделать, так это представить на осях x и y не метки моих экземпляров, а цветной индикатор (представьте себе что-то вроде небольшого пальца на каждой оси), где каждый цвет представляет другую переменную, связанную с каждым экземпляром (скажем, У меня есть эта информация, хранящаяся в списке с именем labels) плюс еще одна легенда для такого рода информации рядом с той, которая указывает цвета тепловой карты (такая же, как для lmplot). Важно, чтобы две информации имели разные цветовые палитры.

Возможно ли такое в Сиборне?

ОБНОВЛЕНИЕ

Я ищу clustermap, как правильно предложено.

sns.clustermap(sim_mat, row_colors=label_cols, col_colors=label_cols
    row_cluster=False, col_cluster=False)

Вот что я получаю, кстати, точки и линии слишком маленькие, и я не вижу способа увеличить их в документации. Хотелось бы

Кроме того, как я могу добавить легенду и поставить две легенды рядом друг с другом в одном и том же положении?

введите описание изображения здесь


person rano    schedule 16.01.2015    source источник
comment
Похоже, вы могли бы захотеть использовать clusterplot с боковыми цветами и отключенной кластеризацией. См. Этот пример stanford.edu/~mwaskom/software/seaborn/examples/ < / а>.   -  person mwaskom    schedule 16.01.2015


Ответы (3)


Есть два варианта:

Во-первых, heatmap - это показатель уровня осей, поэтому вы можете настроить основные большие основные оси тепловых карт для корреляционной матрицы и расположить их по бокам тепловыми картами, которые вы затем передадите себе. Это будет немного поработать, но даст вам полный контроль над тем, как все работает.

Это более или менее вариант в clustermap, поэтому я собираюсь продемонстрировать, как это сделать здесь. Это немного похоже на хитрость, но это сработает.

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

networks = sns.load_dataset("brain_networks", index_col=0, header=[0, 1, 2])
network_labels = networks.columns.get_level_values("network")
network_pal = sns.cubehelix_palette(network_labels.unique().size,
                                    light=.9, dark=.1, reverse=True,
                                    start=1, rot=-2)
network_lut = dict(zip(map(str, network_labels.unique()), network_pal))

network_colors = pd.Series(network_labels).map(network_lut)

Затем мы вызываем clustermap, чтобы сделать основной сюжет.

g = sns.clustermap(networks.corr(),

                  # Turn off the clustering
                  row_cluster=False, col_cluster=False,

                  # Add colored class labels
                  row_colors=network_colors, col_colors=network_colors,

                  # Make the plot look better when many rows/cols
                  linewidths=0, xticklabels=False, yticklabels=False)

Боковые цвета рисуются с помощью тепловой карты, которую matplotlib считает количественными данными, и поэтому нет простого способа получить легенду прямо из нее. Вместо этого мы добавим невидимую полосу с нужными цветами и метками, а затем добавим легенду для этого.

for label in network_labels.unique():
    g.ax_col_dendrogram.bar(0, 0, color=network_lut[label],
                            label=label, linewidth=0)
g.ax_col_dendrogram.legend(loc="center", ncol=6)

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

g.cax.set_position([.15, .2, .03, .45])
g.savefig("clustermap.png")

введите описание изображения здесь

person mwaskom    schedule 16.01.2015

Основываясь на приведенном выше ответе, я думаю, что стоит отметить возможность использования нескольких цветовых уровней для меток - как указано в документах кластерной карты. ({строка, столбец} _colors). Мне не удалось найти пример нескольких уровней, поэтому я решил поделиться примером здесь.

networks = sns.load_dataset("brain_networks", index_col=0, header=[0, 1, 2])

сетевой уровень

network_labels = networks.columns.get_level_values("network")
network_pal = sns.cubehelix_palette(network_labels.unique().size, light=.9, dark=.1, reverse=True, start=1, rot=-2)
network_lut = dict(zip(map(str, network_labels.unique()), network_pal))

Создать индекс, используя столбцы для сетей

network_colors = pd.Series(network_labels, index=networks.columns).map(network_lut)

уровень узла

node_labels = networks.columns.get_level_values("node")
node_pal = sns.cubehelix_palette(node_labels.unique().size)
node_lut = dict(zip(map(str, node_labels.unique()), node_pal))

Создать индекс, используя столбцы для узлов

node_colors = pd.Series(node_labels, index=networks.columns).map(node_lut)

Создание фрейма данных для уровней цвета строк и столбцов

network_node_colors = pd.DataFrame(network_colors).join(pd.DataFrame(node_colors))

создать clustermap

g = sns.clustermap(networks.corr(),
# Turn off the clustering
row_cluster=False, col_cluster=False,
# Add colored class labels using data frame created from node and network colors
row_colors = network_node_colors,
col_colors = network_node_colors,
# Make the plot look better when many rows/cols
linewidths=0,
xticklabels=False, yticklabels=False,
center=0, cmap="vlag")

создайте две легенды - по одной для каждого уровня, создав невидимые столбчатые и строчные диаграммы (как указано выше)

сетевая легенда

from matplotlib.pyplot import gcf

for label in network_labels.unique():
    g.ax_col_dendrogram.bar(0, 0, color=network_lut[label], label=label, linewidth=0)

l1 = g.ax_col_dendrogram.legend(title='Network', loc="center", ncol=5, bbox_to_anchor=(0.47, 0.8), bbox_transform=gcf().transFigure)

легенда узла

for label in node_labels.unique():
    g.ax_row_dendrogram.bar(0, 0, color=node_lut[label], label=label, linewidth=0)

l2 = g.ax_row_dendrogram.legend(title='Node', loc="center", ncol=2, bbox_to_anchor=(0.8, 0.8), bbox_transform=gcf().transFigure)

plt.show()

введите описание изображения здесь

person David Deery    schedule 08.11.2018
comment
Это ТОЧНО то, что я искал сегодня. Это один из самых полезных ответов, с которыми я когда-либо сталкивался; Сам я бы никогда не догадалась. Спасибо!! - person KsEuro; 24.04.2021

Когда используются обе дендрограммы, можно также добавить новую скрытую ось и нарисовать легенду.

ax= f.add_axes((0,0,0,0))
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)

for label in node_labels.unique():
    ax.bar(0, 0, color=node_lut[label], label=label, linewidth=0)

l2 = g.ax_row_dendrogram.legend(title='Node', loc="center", ncol=2, bbox_to_anchor=(0.8, 0.8), bbox_transform=f.transFigure)
person KieserS    schedule 23.05.2019