You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas绘图图例与颜色映射问题求助

数据可视化问题解答

背景与代码

现有如下数据处理代码:

import numpy as np
import pandas as pd

# Data creation
d1 = pd.DataFrame({
    "Date": ['1/1/2022', '12/15/2010', '6/1/2015', '1/31/2022', '12/31/2010', '3/10/2009', '1/7/2022', '12/9/2010','12/20/2010','1/13/2022'],
    "Item": ['Food', 'Food', 'Gasoline', 'Coffee', 'Coffee', 'PayPal', 'Gasoline', 'Gasoline','Gasoline','Coffee'],
    "Price": [3.89, 7.00, 11, 0.99, 8.01, 99, 76, 50,48,9]
})

# Change Date column to datetime
d1['Date'] = pd.to_datetime(d1['Date'])

# Create MMM-YY column from Date column
d1['MMM-YY'] = d1['Date'].dt.strftime('%b') + '-' + d1['Date'].dt.strftime('%y')

# Sort DataFrame by Date
d1.sort_values('Date', inplace=True)

# Group by MMM-YY, Item and sum Price
d1_sorted = d1.groupby(['MMM-YY','Item'], sort = False)[['Price']].sum()

执行绘图代码:

d1_sorted.unstack().plot(kind = 'bar', title = 'Total Expense', stacked = True, figsize = (15,10), colormap = 'Blues')

得到堆叠条形图后,存在以下三个问题,对应解决方案如下:


问题与解决方案

1. 图例中出现“None,Item”项,是什么?如何移除?

原因:原代码中d1_sorted.unstack()生成的是多层索引(MultiIndex)列,第一层为Price,第二层为Item值。当部分MMM-YY分组下没有对应Item的数据时,会产生NaN值的列,绘图时因多层索引解析异常出现None项。
解决方法:调整groupby后的处理逻辑,直接生成单层索引的DataFrame,避免多层索引:

# 替换原groupby和unstack步骤
d1_sorted = d1.groupby(['MMM-YY','Item'], sort=False)['Price'].sum().unstack(fill_value=0)
# 绘图
d1_sorted.plot(kind='bar', title='Total Expense', stacked=True, figsize=(15,10), colormap='Blues')

这样处理后,列名直接是Item的各个值,不会出现异常图例项。

2. 如何让图例仅显示Item列的值,而非(Price, PayPal)这类元组格式?

原因:原代码中unstack后的列是多层索引,图例默认显示完整的元组列名。
解决方法有两种:

  • 方法一:提前避免多层索引(同问题1的解决方案),直接用单层索引列绘图,图例自动显示Item值。
  • 方法二:手动修改图例标签:
# 执行原绘图代码并获取轴对象
ax = d1_sorted.unstack().plot(kind='bar', title='Total Expense', stacked=True, figsize=(15,10), colormap='Blues')
# 提取元组中的Item部分作为图例标签
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, [label.split(', ')[1][:-1] for label in labels])

或者更简洁的方式,重命名多层索引列:

df_plot = d1_sorted.unstack()
# 只保留第二层索引(Item值)作为列名
df_plot.columns = df_plot.columns.get_level_values(1)
# 绘图
df_plot.plot(kind='bar', title='Total Expense', stacked=True, figsize=(15,10), colormap='Blues')

3. 调整Blues色卡让浅色变深,新手友好的非默认色卡推荐及颜色学习资源

调整Blues色卡的浅色

Matplotlib的Blues色卡是从浅到深的渐变,要跳过最浅的颜色,可以截取色卡的后半段区间:

import matplotlib.cm as cm
# 获取Blues色卡,截取从0.2到1的区间(跳过前20%的浅色)
blues_adjusted = cm.get_cmap('Blues')(np.linspace(0.2, 1, len(d1['Item'].unique())))
# 绘图时使用调整后的颜色
d1_sorted.plot(kind='bar', title='Total Expense', stacked=True, figsize=(15,10), color=blues_adjusted)

新手友好的非默认色卡推荐

  • Seaborn系列:'deep'(颜色饱满区分度高)、'pastel'(柔和不刺眼)、'dark'(深色系适合堆叠图)
  • Matplotlib定性色卡:'tab10'(默认10色,清晰易记)、'tab20'(支持更多分类)
  • ColorBrewer系列:'Set2'(柔和分类色)、'Paired'(成对颜色,适合对比场景)

颜色学习资源

  • 核心原则:分类可视化用高区分度颜色,堆叠图用同色系渐变或亮度区分的互补色,避免红绿色盲难区分的组合;
  • 直接查阅Matplotlib官方色卡示例,记住常用色卡的适用场景即可;
  • Seaborn官方教程里有颜色搭配的详细指导,重点关注分类色、连续色的使用规范。

内容的提问来源于stack exchange,提问作者user603535

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:30:58