带有分类颜色条的树状图注释

dendrogram annotation with categorical colorbar

我想创建一个用分类颜色条注释的树状图。与 dendrogram/colorbar seaborn.clustermap 创建的相同或相似(但显然没有热图!),例如:

import seaborn as sns; sns.set_theme(color_codes=True)
iris = sns.load_dataset("iris")
species = iris.pop("species")

lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)
g = sns.clustermap(iris, row_colors=row_colors, col_cluster=False)

我重现情节的努力让我来到这里:

Z = linkage(iris, method='average', metric='euclidean')
with plt.rc_context({'lines.linewidth': 0.5}):
    fig, ax = plt.subplots(figsize=(3, 6))
    ax.axis('off')
    dd = dendrogram(Z, 
                    ax=ax,
                    truncate_mode=None,
                    leaf_rotation=0, 
                    color_threshold=0,
                    above_threshold_color='black',
                    no_labels=True,
                    orientation='left')
    divider = make_axes_locatable(ax)
    cax = divider.append_axes('right', size='5%', pad=0.05)
    cb = fig.colorbar(ax.collections[0], cax=cax, orientation='vertical')
    cb.outline.set_linewidth(0)

我无法将标签的颜色指定映射到颜色条上的位置。我也想给color:label协会一个图例

以下代码创建了一个聚类图,删除了颜色条和热图,并添加了一个图例:

import seaborn as sns
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle

sns.set_theme(color_codes=True)
iris = sns.load_dataset("iris")
species = iris.pop("species")

lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)
row_colors.name = ""  # remove the name of the row_colors
g = sns.clustermap(iris, row_colors=row_colors, col_cluster=False, dendrogram_ratio=(0.95, 0.03), colors_ratio=0.04, figsize=(12, 6))
g.ax_heatmap.remove()  # remove the heatmap
g.cax.remove()  # remove the color bar
g.ax_row_dendrogram.legend(handles=[Rectangle((0, 0), 0, 0, color=val, label=key) for key, val in lut.items()],
                           title='Species', loc='lower left')
plt.show()