如何基于名称为子图中所有含'?'的条形设置不同颜色
解决Seaborn Countplot中特定类别条形着色问题
需求:将所有带有?的条形标记为蓝色,其余条形标记为红色,但现有代码实现不符合预期,出现颜色分配错位的问题(例如A2列中的f条形被错误染成蓝色)。
错误代码示例
%matplotlib inline import pandas as pd import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import seaborn as sns data=[['a','a','b'],[20,'?',18],['?','?','f'],['?','f','f'],['a','a','?']] col_with_missting_values=['A1','A2','A3'] df=pd.DataFrame(data,columns=col_with_missting_values) def color(coln): if coln=='?': return 'b' else: return 'r' fig, axes = plt.subplots(1, len(col_with_missting_values), figsize=(20, 5)) for colname, ax in zip(col_with_missting_values, axes): ( cr:=[color(x) for x in df[colname]], sns.countplot(df, x=f"{colname}", ax=ax, palette=cr), ax.set_xticklabels(ax.get_xticklabels(), rotation=90), )
问题原因
错误出在palette参数的使用逻辑上:sns.countplot的palette是按统计后类别的出现顺序分配颜色,而非原始数据中每个元素的顺序。你生成的cr是原始每行数据对应的颜色列表,这与countplot的颜色映射逻辑不匹配,导致颜色被错位分配。
正确解决方案
通过生成类别-颜色映射字典,直接为每个类别指定颜色,确保?始终对应蓝色,其他类别对应红色:
%matplotlib inline import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns data=[['a','a','b'],[20,'?',18],['?','?','f'],['?','f','f'],['a','a','?']] col_with_missting_values=['A1','A2','A3'] df=pd.DataFrame(data,columns=col_with_missting_values) fig, axes = plt.subplots(1, len(col_with_missting_values), figsize=(20, 5)) for colname, ax in zip(col_with_missting_values, axes): # 获取当前列的所有唯一类别 categories = df[colname].unique() # 构建类别与颜色的映射字典 color_map = {cat: 'b' if cat == '?' else 'r' for cat in categories} # 传入颜色字典作为palette参数 sns.countplot(data=df, x=colname, ax=ax, palette=color_map) ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
效果说明
修改后,每个子图中?对应的条形都会被染成蓝色,其余类别条形保持红色,完全符合需求。
内容的提问来源于stack exchange,提问作者Lasse Freitag
相关产品推荐
相关产品推荐

