是否可以在df.plot.scatter中设置范数参数?

Is it possible to set the norm parameter in df.plot.scatter?

在进行数据探索时,我更喜欢 df.plot.scatter() 而不是 plt.scatter()。但是我不能

生成数据

n = 1000
data = dict(
    x = np.random.rand(n) + np.random.rand(1)[0],
    y = np.random.rand(n) + np.random.rand(1)[0],
    # color dimension
    z = np.exp(np.random.rand(n)) - np.exp(np.random.rand(n)).mean(),
)
# throw it in a dataframe
df = pd.DataFrame(data)

plt.scatter

绘图

左图使用 CenteredNorm 确保其颜色条以零为中心,无论分布偏斜如何。

cmap='bwr'
fig, (ax1, ax2) = plt.subplots(figsize=(20, 8), ncols=2)
sc = ax1.scatter(x=data['x'], y=data['y'], c=data['z'], cmap=cmap, norm=colors.CenteredNorm())
fig.colorbar(sc, ax=ax1)

sc = ax2.scatter(x=data['x'], y=data['y'], c=data['z'], cmap=cmap)
fig.colorbar(sc, ax=ax2)
plt.show()

df.plot.scatter

绘图
df = pd.DataFrame(data)
fig, (ax1, ax2) = plt.subplots(figsize=(10, 4), ncols=2)
df.plot.scatter(x='x', y='y', c='z', norm=colors.CenteredNorm(), cmap=cmap, ax=ax1)
df.plot.scatter(x='x', y='y', c='z', cmap=cmap, ax=ax2)

plt.show()

尝试与 pandas 内置绘图 API 相同,引发错误:

TypeError: matplotlib.axes._axes.Axes.scatter() got multiple values for keyword argument 'norm'

使用 kwargs 个参数

kwargs = dict(norm=colors.CenteredNorm())
df.plot.scatter(x='x', y='y', c='z',
                cmap=cmap,
                ax=ax1
                **kwargs)

tdy 的代码更正后,该代码段引发了相同的错误:

TypeError: matplotlib.axes._axes.Axes.scatter() got multiple values for keyword argument 'norm'

是否有任何方法可以通过 pandas 内置绘图 API 设置范数参数?

正如@tdy 所提到的,解压 kwargs 并不能解决问题。

函数df.plot.scatter takes the parameters x, y, s, c. Additional kwargs are passed to df.plot。支持以下参数:

  • x
  • y
  • 种类
  • 斧头
  • 子图
  • sharex
  • 夏雷
  • 布局
  • 无花果尺寸
  • use_index
  • 标题
  • 网格
  • 传说
  • 风格
  • logx
  • 日志日志
  • xticks
  • yticks
  • xlim
  • 伊利姆
  • 腐烂
  • 字体大小
  • 颜色图
  • table
  • xerr
  • secondary_y
  • sort_columns

...但它不会采用参数 norm。那将需要扩展 pandas source code.

更新:

从 pandas 1.5.0 开始,norm 参数将按预期与 df.plot.scatter 一起使用。该错误已在 PR #45966.

中得到修复

原错误:

df.plot.scatter passes kwargs to df.plot which passes kwargs to ax.scatter.

问题是 pandas 已经设置了 norm:

plotting/_matplotlib/core.py#L1114-L1122

scatter = ax.scatter(
    data[x].values,
    data[y].values,
    c=c_values,
    label=label,
    cmap=cmap,
    norm=norm,
    **self.kwds,
)

norm 定义为 BoundaryNormNone:

plotting/_matplotlib/core.py#L1095-L1103

if color_by_categorical:
    # ...
    norm = colors.BoundaryNorm(bounds, cmap.N)
else:
    norm = None

因此通过 kwargs 传递另一个 norm 将产生“多值”错误。

这可以在纯 matplotlib 中重现:

fig, ax = plt.subplots()
ax.scatter(0, 42, norm=None, **{'norm': colors.CenteredNorm()})

# TypeError: matplotlib.axes._axes.Axes.scatter() got multiple values for keyword argument 'norm'