Seaborn箱线图图例显示异常问题求助
Seaborn箱线图图例异常问题解决方法
问题描述
使用Seaborn绘制数据集所有数值列的箱线图时,由于sns.boxplot没有内置label参数,直接调用plt.legend(columns)会导致图例显示异常(每个标签对应多个重复的标记)。
原代码
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from itertools import cycle colors = ['maroon','grey','navy','burlywood','black','aliceblue','beige'] colorCycle = cycle(colors) sns.set_style('darkgrid') df = pd.read_csv('dm_office_sales.csv') numericClassifier = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64'] newdf = df.select_dtypes(numericClassifier) columns = newdf.columns.tolist() n = len(columns) sns.boxplot(data=df[columns],palette='bright') plt.suptitle('Boxplots').set_fontname('ariel') plt.legend(columns,loc='upper left') plt.tight_layout() plt.show()
问题原因
sns.boxplot绘制的每个箱线图由多个可视化元素(箱体、须线、中位数线等)组成,直接传递列名给plt.legend()会把这些元素全部纳入图例生成逻辑,导致重复标记的异常显示。
解决方案
方案一:手动提取箱线图元素创建图例
保留Seaborn默认样式,手动提取每个箱线图的箱体元素作为图例手柄:
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns sns.set_style('darkgrid') df = pd.read_csv('dm_office_sales.csv') # 筛选所有数值列 numeric_cols = df.select_dtypes(include=['int16', 'int32', 'int64', 'float16', 'float32', 'float64']).columns.tolist() # 绘制箱线图并获取Axes对象 ax = sns.boxplot(data=df[numeric_cols], palette='bright') # 设置标题(注意字体名拼写应为Arial) ax.set_title('Boxplots', fontname='Arial') # 提取每个箱线图的第一个箱体元素作为图例手柄 handles = [ax.patches[i] for i in range(len(numeric_cols))] # 创建图例 ax.legend(handles, numeric_cols, loc='upper left') plt.tight_layout() plt.show()
方案二:使用Matplotlib原生箱线图函数
Matplotlib的boxplot支持直接设置labels参数,配合Seaborn风格使用:
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns sns.set_style('darkgrid') df = pd.read_csv('dm_office_sales.csv') numeric_cols = df.select_dtypes(include=['int16', 'int32', 'int64', 'float16', 'float32', 'float64']).columns.tolist() # 将数值列数据转为列表格式 data = [df[col].values for col in numeric_cols] # 绘制箱线图,设置labels并开启填充模式 plt.boxplot(data, labels=numeric_cols, patch_artist=True) # 应用Seaborn的bright调色板 colors = sns.color_palette('bright', len(numeric_cols)) for patch, color in zip(plt.gca().patches, colors): patch.set_facecolor(color) plt.title('Boxplots', fontname='Arial') plt.legend(loc='upper left') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Raaghav Rammohan
相关产品推荐
相关产品推荐

