如何为Seaborn displot按Crop列设置差异化颜色
按Crop列单独设置Seaborn displot的颜色方案
要实现按Crop列分别设置不同调色板,你可以在绘制完displot后,遍历每个子图,根据子图对应的Crop类别单独修改直方图颜色。具体实现如下:
1. 准备包含Corn和Soy的测试数据
你提供的原始数据全为Corn,先补充Soy样本以便验证效果:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd # 扩展数据集,加入Soy类别样本 df_melted = pd.DataFrame({ 'Sink_ID': ['100012_HUC8_09020204', '100012_HUC8_09020204', '100017_HUC8_09020204', '100017_HUC8_09020204', '100029_HUC8_09020204', '100029_HUC8_09020204', '100136_HUC8_09020205', '100136_HUC8_09020205', '100147_HUC8_09020204', '100147_HUC8_09020204', '100012_Soy', '100012_Soy', '100017_Soy', '100017_Soy'], 'Year': [2005]*14, 'Date_Range': ['07-10']*14, 'WUVR': [1.11, 1.00, 0.53, 0.70, 0.98, 1.02, 1.08, 1.38, 0.67, 0.72, 0.85, 0.92, 0.61, 0.78], 'Temp': [24.08, 21.55, 24.08, 21.73, 24.03, 21.66, 23.88, 21.39, 24.08, 21.73, 23.5, 21.2, 23.7, 21.4], 'Precip': [0.08, 2.67, 0.91, 4.66, 0.72, 4.31, 0.14, 2.28, 0.91, 4.66, 0.12, 2.5, 0.88, 4.4], 'Crop': ['Corn']*10 + ['Soy']*4, 'NDVI_Type': ['NDVI_wet', 'NDVI_dry']*7, # 保留两种NDVI类型用于区分hue 'NDVI_Value': [0.84, 0.75, 0.32, 0.45, 0.63, 0.60, 0.64, 0.70, 0.37, 0.40, 0.78, 0.68, 0.55, 0.48], 'Intervals': ['07-10 to 08-06']*14 }) # 模拟df_intervals数据集 df_intervals = pd.DataFrame({'Intervals': ['07-10 to 08-06']})
2. 定义按Crop分组的颜色规则
创建字典明确每种Crop对应的NDVI_Type颜色,顺序要和hue的类别顺序一致:
# 颜色映射:key为Crop名称,value为对应NDVI_Type的颜色列表 crop_color_map = { 'Corn': ['#ff3333', '#33cc33'], # Corn对应红色、绿色 'Soy': ['#ff9933', '#3399ff'] # Soy对应橙色、蓝色 }
3. 绘制displot并修改子图颜色
先绘制基础displot,再遍历每个子图替换对应颜色:
sns.set_theme(style="white", palette=None) # 创建分面直方图 g = sns.displot( data=df_melted, x='NDVI_Value', hue='NDVI_Type', row='Intervals', col='Crop', binwidth=0.01, height=3, aspect=2.5, facet_kws=dict(margin_titles=False), row_order=df_intervals['Intervals'].tolist() ) # 统一设置x轴参数并修改子图颜色 for ax in g.axes.flatten(): ax.set_xlim(0, 1) ax.title.set_fontsize(14) # 获取当前子图对应的Crop类别 crop_label = g.col_names[g.axes.flatten().tolist().index(ax)] # 获取对应颜色列表 colors = crop_color_map[crop_label] # 按hue分组分配颜色 hue_count = len(g.hue_names) patch_per_hue = len(ax.patches) // hue_count for i, patch in enumerate(ax.patches): group_idx = i // patch_per_hue patch.set_facecolor(colors[group_idx]) plt.xticks([0, 0.25, 0.5, 0.75, 1], labels=['0', '0.25', '0.5', '0.75', '1']) plt.show()
核心逻辑说明
- 通过
crop_color_map绑定Crop与hue的颜色对应关系,避免全局调色板的影响。 - 遍历子图时,通过分面对象的
col_names精准获取当前子图的Crop类别。 - 将子图中的patch按hue类别数量分组,为每组分配对应颜色,实现分Crop的颜色定制。
内容的提问来源于stack exchange,提问作者Ekkehardt Rosasee
相关产品推荐
相关产品推荐

