如何为图表的颜色和标记创建独立的图例分区
解决双特征散点图的双图例问题
需求说明
在同一张图中绘制两个特征,需要生成两类独立图例:
- 物种图例:用颜色区分不同物种,无重复颜色条目
- 特征图例:用标记区分两个特征(圆形对应特征1,星号对应特征2)
当前代码生成的图例会重复显示每个物种与特征的组合,不符合需求,以下是修正方案:
修正后代码
import seaborn as sns import matplotlib.pyplot as plt import random import matplotlib.colors as mcolors from matplotlib.lines import Line2D random.seed(5) iris = sns.load_dataset("iris") species_list = list(iris.species.unique()) colors_name = list(mcolors.CSS4_COLORS.keys()) color_species = random.sample(colors_name, len(species_list)) fig, ax = plt.subplots(1, 1, figsize=(10, 6)) # 绘制两个散点图,关闭自动生成图例 sns.scatterplot(data=iris, edgecolor="black", x=iris.index.values, y='sepal_length', s=50, alpha=0.8, hue='species', palette=color_species, ax=ax, legend=False) sns.scatterplot(data=iris, edgecolor="black", marker='*', x=iris.index.values, y='sepal_width', s=90, alpha=0.8, hue='species', palette=color_species, ax=ax, legend=False) # 创建物种颜色图例:提取唯一的物种-颜色对应条目 handles_species, labels_species = ax.get_legend_handles_labels() # 取前N个条目(N为物种数量),避免重复 unique_handles = handles_species[:len(species_list)] unique_labels = labels_species[:len(species_list)] legend_species = ax.legend(handles=unique_handles, labels=unique_labels, loc='upper right', bbox_to_anchor=(1.5, 1), title='物种') # 创建特征标记图例:自定义标记与标签对应关系 handles_features = [ Line2D([], [], marker='o', color='black', linestyle='None', markersize=7, label='特征1'), Line2D([], [], marker='*', color='black', linestyle='None', markersize=10, label='特征2') ] legend_features = ax.legend(handles=handles_features, loc='upper right', bbox_to_anchor=(1.5, 0.7), title='特征') # 重新添加物种图例,避免被第二个图例覆盖 ax.add_artist(legend_species) ax.set_xlabel('样本') ax.set_ylabel('特征1 和 特征2') plt.tight_layout() plt.show()
关键步骤说明
- 关闭自动图例:绘制散点图时设置
legend=False,防止生成重复的物种+特征组合图例 - 提取唯一物种图例:从绘图句柄中取前N个条目(N等于物种数量),得到无重复的颜色-物种对应关系
- 自定义特征图例:用
Line2D创建仅包含标记形状的图例条目,颜色设为黑色不干扰物种颜色展示 - 双图例布局:通过
bbox_to_anchor调整两个图例的位置,上下排列避免重叠;调用add_artist保留第一个图例,防止被第二个图例覆盖
内容的提问来源于stack exchange,提问作者JCV
相关产品推荐
相关产品推荐

