如何在Seaborn lmplot中设置与hue独立的标记样式?
解决Seaborn lmplot中标记形状与hue分类独立的问题
你可以通过访问FacetGrid中的Axes对象来修改散点标记,无需借助scatter_kws传递标签,直接基于原始数据的marker列匹配修改即可。以下是两种可行的解决方案:
方案一:修改已绘制的lmplot散点标记
先正常绘制lmplot,再遍历散点集合,根据数据中的标记信息逐一修改:
import seaborn as sns import pandas as pd snsdf = pd.DataFrame({'x' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'y' : [9, 9, 8, 6, 6, 4, 4, 3, 1, 1], 'hue' : ['tree', 'animal', 'animal', 'tree', 'animal'] * 2, 'marker' : ['o', 'o', '<', '<', 'o', '<', '<', '<', 'o', 'o'] }) # 常规绘制lmplot,hue控制颜色 g = sns.lmplot(data=snsdf, x='x', y='y', hue='hue') # 获取绘图的Axes对象 ax = g.axes[0, 0] # 提取散点集合(lmplot中第一个collection是散点) scatter = ax.collections[0] # 获取所有散点的坐标 points = scatter.get_offsets() # 遍历每个点,匹配数据中的标记并修改 for i, (x_coord, y_coord) in enumerate(points): # 匹配数据中对应坐标的行(若有重复坐标,可改用索引匹配) match_row = snsdf[(snsdf['x'] == x_coord) & (snsdf['y'] == y_coord)] if not match_row.empty: target_marker = match_row['marker'].values[0] # 获取对应标记的路径,替换当前点的路径 marker_idx = sns.scatterplot.markers.index(target_marker) scatter._paths[i] = scatter.get_paths()[marker_idx]
方案二:拆分绘制拟合线与散点(更灵活)
直接分开绘制不同hue的拟合线,再根据marker列绘制散点,完全独立控制颜色和标记:
import seaborn as sns import pandas as pd import matplotlib.pyplot as plt snsdf = pd.DataFrame({'x' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'y' : [9, 9, 8, 6, 6, 4, 4, 3, 1, 1], 'hue' : ['tree', 'animal', 'animal', 'tree', 'animal'] * 2, 'marker' : ['o', 'o', '<', '<', 'o', '<', '<', '<', 'o', 'o'] }) fig, ax = plt.subplots() # 绘制不同hue的拟合线(不显示散点) sns.regplot(data=snsdf[snsdf['hue'] == 'tree'], x='x', y='y', ax=ax, scatter=False, color=sns.color_palette()[0]) sns.regplot(data=snsdf[snsdf['hue'] == 'animal'], x='x', y='y', ax=ax, scatter=False, color=sns.color_palette()[1]) # 根据marker列绘制散点,保持hue对应的颜色 for marker_type in snsdf['marker'].unique(): marker_subset = snsdf[snsdf['marker'] == marker_type] for hue_val in marker_subset['hue'].unique(): hue_marker_subset = marker_subset[marker_subset['hue'] == hue_val] # 选择对应hue的颜色 color = sns.color_palette()[0] if hue_val == 'tree' else sns.color_palette()[1] ax.scatter(hue_marker_subset['x'], hue_marker_subset['y'], marker=marker_type, color=color) # 自定义图例 plt.legend(['tree 拟合线', 'animal 拟合线', '标记 o', '标记 <']) plt.show()
内容的提问来源于stack exchange,提问作者BML
相关产品推荐
相关产品推荐

