首页 > 解决方案 > pandas.plot 参数 c vs s

问题描述

我在 python 的机器学习书中有以下代码:

copy_set.plot(kind = "scatter" , x = "longitude" , 
              y = "latitude" , alpha = 0.4 , 
              s = copy_set[ "population" ], 
              label = "population" , figsize=(10,7), 
              c = "median_house_value" , cmap = plt.get_cmap ( "jet" ) ) 

median_house_value并且population是数据框中的两列copy_set。我不明白为什么s我必须使用参数,copy_set['population']但参数c可以只使用列名median_house_value。当我尝试仅将列名用于参数s时,我收到一条错误消息:

TypeError: ufunc 'sqrt' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

标签: pythonpandasmatplotlib

解决方案


非常好的问题。df.plot是几个 matplotlib 绘图函数的包装器。对于kind="scatter"matplotlib 的scatter函数将被调用。大多数参数df.plot()首先转换为Series您从相应名称的数据框列中获得的数据。

例如

df.plot(x="lon", y="lat")

将转换为

ax.scatter(x=df["lon"].values, y=df["lat"].values)

剩余的参数被传递给 scatter,因此

df.plot(x="lon", y="lat", some_argument_pandas_doesnt_know=True)

将导致

ax.scatter(x=df["lon"].values, y=df["lat"].values, some_argument_pandas_doesnt_know=True)

因此,虽然 pandas 转换参数x, y, c,但它不会为s. s因此被简单地传递给ax.scatter,但 matplotlib 函数不知道某些字符串的"population"含义。
对于传递给 matplotlib 函数的参数,需要坚持 matplotlib 的签名,并且在s直接提供数据的情况下。

但是请注意,matplotlib 的 scatter 本身也允许使用字符串作为其参数。然而,这需要告诉它应该从哪个数据集中获取它们。这是通过data参数完成的。因此,以下工作正常,并且将是与问题中的 pandas 调用等效的 matplotlib:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np; np.random.seed(42)

df = pd.DataFrame(np.random.rand(20,2), columns=["lon", "lat"])
df["pop"] = np.random.randint(5,300,size=20)
df["med"] = np.random.rand(20)*1e5

fig, ax = plt.subplots(figsize=(10,7))
sc = ax.scatter(x = "lon", y = "lat", alpha = 0.4, 
                s = "pop", label = "population" , 
                c = "med" , cmap = "jet", data=df)
fig.colorbar(sc, label="med")
ax.set(xlabel="longitude", ylabel="latitude")

plt.show()

最后,您现在可能会问,通过data参数向 matplotlib 提供数据是否同样不可能通过 pandas 包装器传递。不幸的是不是,因为 pandasdata在内部使用作为参数,这样它就不会被传递。因此,您的两个选择是:

  1. s在问题中使用 pandas 并通过参数而不是列名提供数据本身。
  2. 如此处所示使用 matplotlib 并为所有参数使用列名。(或者使用数据本身,这是您在查看 matplotlib 代码时最常看到的。)

推荐阅读