从Pandas DataFrame绘制时,控制颜色,图例,每个x

时间:2018-05-10 00:08:44

标签: python pandas matplotlib

我有一个包含3列的数据框。我想在x轴上绘制col1,在y轴上绘制col2和col3。 Col1具有重复值,因此对于每个x值,都存在重复的y值。

示例数据框:

DF = pd.DataFrame({"name": ["Alice", "Alice", "Charles", "Charles", "Kumar", "Kumar"],
              "height": [124, 126, 169, 170, 175, 174],
              "weight": [100, 105, 123, 125, 139, 140]})

DF 

    name    height  weight
  0 Alice   124     100
  1 Alice   126     105
  2 Charles 169     123
  3 Charles 170     125
  4 Kumar   175     139
  5 Kumar   174     140

我想:

A)每个人只在x轴上出现一次

B)将所有高度保持为一种颜色,并将所有权重设置为另一种颜色,并使用准确,不重复的图例

到目前为止,我可以得到A或B,而不是两者。以下是我尝试的和输出。对于A,这很有帮助(Python Scatter Plot with Multiple Y values for each X

对于A:

f = DF.groupby("name", as_index=False).agg({"height":lambda x: tuple(x), "weight":lambda x: tuple(x)})
for x, (y1, y2) in enumerate(zip(f.height.values.tolist(), f.weight.values.tolist()), start=1):

    plt.scatter([x] * len(y1), y1, color='green', marker='o', label="height")
    plt.scatter([x] * len(y2), y2, color='blue', marker='o', label="weight")

plt.xticks(np.arange(1, len(f.name.values) +1))
plt.axes().set_xticklabels(f.name.values.tolist())
plt.legend(loc="best")
plt.show()

对于B:

ax = DF.plot(style="o", figsize=(7, 5), xlim=(-1, 6))
ax.set_xticks(DF.index)
ax.set_xticklabels(DF.name, rotation=90)
plt.show()

enter image description here

enter image description here

2 个答案:

答案 0 :(得分:3)

因为您有2列,您可以绘制2个散点图,每个散点图都有自己的标签。

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({"name": ["Alice", "Alice", "Charles", "Charles", "Kumar", "Kumar"],
              "height": [124, 126, 169, 170, 175, 174],
              "weight": [100, 105, 123, 125, 139, 140]})

plt.scatter(df.name, df.height, label="height")
plt.scatter(df.name, df.weight, label="weight")
plt.legend()
plt.show()

enter image description here

拥有更多列,您当然可以循环使用

for col in ["height", "weight"]:
    plt.scatter(df.name, df[col], label=col)

答案 1 :(得分:1)

一个简单的选择是直接使用matplotlib绘图,而不是使用pandas.DataFrame.plot方法。为了得到一个独立于列数和行数等的解决方案,' name'列可以设置为索引。无需循环遍历列。因此,代码将是:

OutOfMembryException

生成:

plot1

另一个选择是通过替换字符串值(不是用于绘图,而不是索引,这就是它们不在同一个地方的原因)来调整选项B。

DF.set_index('name',inplace=True)
plt.plot(DF.index,DF.values,'o')
plt.legend(DF.columns)

为了获得良好的映射,使用了删除重复项后索引和名称之间的逆映射,对于ticks和ticklabels,也使用了相同的值。

请注意,替换是在绘图之前执行的,并且未存储,因此x_labels = DF['name'].drop_duplicates() map_x_vals = {v: k for k, v in x_labels.to_dict().items()} ax = DF.replace({'name' : map_x_vals}).plot(x='name',style="o", figsize=(7, 5), xlim=(-1, 6)) ax.set_xticks(x_labels.index) ax.set_xticklabels(x_labels.values, rotation=90) plt.show() 未被修改。

生成的图如下:

plot2