已使用hue参数时如何修改指定箱线图的颜色
解决方案
方法1:直接修改已绘制的箱线图元素
Seaborn绘制的箱线图中,每个箱体对应一个Patch对象,箱线、须线等对应Line2D对象。你可以在绘图后直接定位这些元素并修改颜色,无需调整原始数据结构。
先修正代码中变量名不统一的问题(将df改为genes_df),再添加颜色修改逻辑:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns data = { 'TPM': [358934.30, 21984.51, 621008.07, 0.000254, 123456.78, 98765.43, 456.78, 0.000004, 28413.26, 111.11, 98765.43, 8888.88, 3456.78, 789.01, 987654.32, 0.123456, 7890.12, 12345.67, 0.000001, 987654.32, 0.000001, 12345.67, 987.65, 0.000001], 'Type': ['tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal'], 'Distance': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3] } genes_df = pd.DataFrame(data) plt.figure(figsize=(30, 15)) ax = sns.boxplot(data=genes_df, x='Distance', y='TPM', hue='Type', width=0.9) plt.yscale('log') plt.legend(bbox_to_anchor=(0.95, 0.98), loc='upper left') plt.xticks(rotation=90) # 指定需要修改的箱线图索引(第1个为索引0,第4个为索引3) target_boxes = [0, 3] # 修改箱体填充色 for idx, patch in enumerate(ax.artists): if idx in target_boxes: patch.set_facecolor('red') # 修改箱线、须线、中位数线的颜色(每个箱体对应6条线) for line_idx, line in enumerate(ax.lines): box_idx = line_idx // 6 if box_idx in target_boxes: line.set_color('darkred') line.set_linewidth(2) plt.show()
方法2:结合标记列自定义调色板
给数据添加差异标记列,再通过调色板对指定分组单独设置颜色,适合需要批量标记差异组的场景:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns data = { 'TPM': [358934.30, 21984.51, 621008.07, 0.000254, 123456.78, 98765.43, 456.78, 0.000004, 28413.26, 111.11, 98765.43, 8888.88, 3456.78, 789.01, 987654.32, 0.123456, 7890.12, 12345.67, 0.000001, 987654.32, 0.000001, 12345.67, 987.65, 0.000001], 'Type': ['tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal', 'tumour', 'normal'], 'Distance': [1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3] } genes_df = pd.DataFrame(data) # 添加差异标记列:标记目标分组为差异组 genes_df['is_diff'] = genes_df.apply( lambda row: 'diff' if (row['Distance'] ==1 and row['Type'] =='tumour') or (row['Distance'] ==2 and row['Type'] =='normal') else 'normal', axis=1 ) plt.figure(figsize=(30, 15)) ax = sns.boxplot(data=genes_df, x='Distance', y='TPM', hue='Type', width=0.9) plt.yscale('log') plt.legend(bbox_to_anchor=(0.95, 0.98), loc='upper left') plt.xticks(rotation=90) # 遍历箱体,根据分组信息设置颜色 for box_idx, box in enumerate(ax.artists): # 解析当前箱体的Type和Distance type_val = box.get_label().split('=')[1] dist_val = ax.get_xticks()[box_idx // 2] # 判断是否为目标差异组 if (dist_val ==1 and type_val =='tumour') or (dist_val ==2 and type_val =='normal'): box.set_facecolor('red') # 修改对应线条颜色 for line in ax.lines[box_idx*6 : (box_idx+1)*6]: line.set_color('darkred') line.set_linewidth(2) plt.show()
注意事项
- 方法1更直接,适合快速修改指定位置的箱线图;方法2更灵活,便于后续扩展标记更多差异组。
- 每个箱线图对应6条Line2D元素(箱线、须线、中位数线等),因此线条索引按
箱体索引*6到(箱体索引+1)*6-1的范围划分。
内容的提问来源于stack exchange,提问作者Jeanie
相关产品推荐
相关产品推荐

