matplotlib绘制柱状图如何为每个柱子设置唯一不重复颜色
问题原因
- 默认配色重复:matplotlib 默认全局色板的颜色数量固定,当绘制的柱子总数超过色板长度时,会自动从头循环取色,因此出现每隔固定数量柱子颜色重复的问题。
- 自定义颜色全同:循环绘制单根柱子时,每次都将完整的颜色列表传入
color参数,matplotlib 会取列表第一个颜色用于当前绘制的单根柱子,最终所有柱子都显示为列表第一个颜色。另外原代码生成颜色列表时长度取的是DataFrame行数len(df),和实际需要绘制的、存在NaN值的字段数量不匹配。
修正方案
不需要逐根柱子循环绘制,直接过滤掉NaN占比为0的字段后一次性绘制所有柱子,传入和柱子数量等长的颜色列表即可自动分配唯一颜色。如果字段数量较多,可拼接matplotlib内置的多组离散色板获取足够多的唯一颜色,无需手动枚举颜色值。
修正后可直接运行的代码:
import matplotlib.pyplot as plt import numpy as np from matplotlib import cm # 计算各字段NaN值百分比 per = df.isna().mean().round(4) * 100 # 过滤掉无NaN值的字段 per_plot = per[per > 0] # 拼接内置离散色板,最多支持60个字段的唯一配色,可按需增减 color_pool = cm.tab20.colors + cm.tab20b.colors + cm.tab20c.colors my_colors = color_pool[:len(per_plot)] f, ax = plt.subplots(figsize=(25, 12), dpi=200) # 一次性绘制所有柱子,自动按顺序分配颜色 bars = ax.bar(per_plot.index, per_plot.values, color=my_colors) # 添加柱子顶部的数值标签 for idx, val in enumerate(per_plot.values): ax.text(idx, val + 0.5, str(np.round(val, 2)), ha='center') # 图表样式设置 ax.set_xticklabels([]) ax.set_xticks([]) plt.title('NaN Value percentage in the dataset') plt.ylim(0, 115) plt.ylabel('Percentage') plt.xlabel('Columns') plt.legend(bars, per_plot.index, loc='upper left') plt.show()
如果你要使用自定义颜色集合,只需保证传入的颜色列表长度和待绘制柱子数量一致即可。如果字段数量远大于可用的唯一颜色数量,才需要用
itertools.cycle做循环取色,此时会出现颜色重复。
内容的提问来源于stack exchange,提问作者user17416440
相关产品推荐
相关产品推荐

