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

使用pandas groupby绘制散点图的颜色映射警告及同色问题

Pandas groupby绘制散点图的颜色映射问题

问题描述

使用pandas的groupby绘制散点图时,两类数据颜色完全相同,同时出现颜色映射警告。示例代码如下:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(data= {'class': ['A']*5 + ['B']*5,
                         'index': [i for i in range(10)],
                         'data': [i for i in range(5)] + [i+1 for i in range(5)]})
# Plotting
fig, ax = plt.subplots()
for key, grp in df.groupby('class'):
    grp.plot.scatter(ax=ax, x='index', y='data', label=key)

运行后出现警告:

/opt/miniconda3/lib/python3.8/site-packages/pandas/plotting/_matplotlib/core.py:1114: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
scatter = ax.scatter(

但如果用df.plot(ax=ax, x='index', y='data', label=key)替代散点图方法,颜色显示正常且无警告。

原因分析

  1. 颜色循环机制差异:
    • pandas的plot.scatter()本质是直接调用matplotlib的ax.scatter(),每次调用都会从颜色循环的起始位置取色,不会自动推进颜色索引,导致多次调用时颜色重复。
    • 而df.plot()默认绘制折线图,pandas会自动维护颜色循环状态,每次调用取下一个颜色,因此分组后的颜色能自动区分。
  2. 警告产生原因:
    plot.scatter()默认尝试使用颜色映射(cmap),但需要通过c参数传入数值型数据实现颜色映射。代码中未提供c参数,因此触发警告,cmap参数被忽略,最终使用默认颜色。

解决方案

方法1:手动指定颜色列表

预先定义颜色列表,循环中按索引取色:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(data= {'class': ['A']*5 + ['B']*5,
                         'index': [i for i in range(10)],
                         'data': [i for i in range(5)] + [i+1 for i in range(5)]})

colors = ['red', 'blue']  # 对应A、B两类的颜色
fig, ax = plt.subplots()
for idx, (key, grp) in enumerate(df.groupby('class')):
    grp.plot.scatter(ax=ax, x='index', y='data', label=key, color=colors[idx])
plt.legend()
plt.show()

方法2:使用matplotlib原生scatter方法

绕开pandas的plot包装,直接调用matplotlib的scatter,利用其自动颜色循环:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(data= {'class': ['A']*5 + ['B']*5,
                         'index': [i for i in range(10)],
                         'data': [i for i in range(5)] + [i+1 for i in range(5)]})

fig, ax = plt.subplots()
for key, grp in df.groupby('class'):
    ax.scatter(grp['index'], grp['data'], label=key)
plt.legend()
plt.show()

方法3:利用seaborn简化分组绘图

seaborn的relplot可直接按列分组绘图,无需手动循环:

import pandas as pd
import seaborn as sns

df = pd.DataFrame(data= {'class': ['A']*5 + ['B']*5,
                         'index': [i for i in range(10)],
                         'data': [i for i in range(5)] + [i+1 for i in range(5)]})

sns.relplot(data=df, x='index', y='data', hue='class', kind='scatter')
plt.show()

使用的包版本

  • pandas: 1.4.3
  • matplotlib: 3.6.2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:10:25