如何在循环通过pandas数据帧时标记matplotlib散点图中的数据点?

时间:2016-12-05 16:38:24

标签: python-3.x pandas matplotlib label scatter-plot

我有一个pandas数据框,包括以下列:

label = ('A' , 'D' , 'K', 'L', 'P')
x = (1 , 4 , 9, 6, 4)
y = (2 , 6 , 5, 8, 9)
plot_id = (1 , 1 , 2, 2, 3)

我想创建3个单独的散点图 - 每个人plot_id一个。因此,第一个散点图应该包含plot_id == 1的所有条目,因此包括点(1,2)和(4,6)。每个数据点都应标有label。因此,第一个图应该有标签AB

我知道我可以使用annotate标记,并且我熟悉for循环。但我不知道如何将两者结合起来。

我希望我能够发布迄今为止我所做的更好的代码片段 - 但它真的很糟糕。这是:

for i in range(len(df.plot_id)):
    plt.scatter(df.x[i],df.y[i])
    plt.show()

不幸的是,我得到了所有这些。关于如何处理的任何想法?

2 个答案:

答案 0 :(得分:4)

更新回答
保存单独的图像文件

def annotate(row, ax):
    ax.annotate(row.label, (row.x, row.y),
                xytext=(10, -5), textcoords='offset points')

for pid, grp in df.groupby('plot_id'):
    ax = grp.plot.scatter('x', 'y')
    grp.apply(annotate, ax=ax, axis=1)
    plt.savefig('{}.png'.format(pid))
    plt.close()

<强> 1.png
enter image description here

<强> 2.png
enter image description here

<强> 3.png
enter image description here

旧答案
对于那些想要这样的人

def annotate(row, ax):
    ax.annotate(row.label, (row.x, row.y),
                xytext=(10, -5), textcoords='offset points')

fig, axes = plt.subplots(df.plot_id.nunique(), 1)
for i, (pid, grp) in enumerate(df.groupby('plot_id')):
    ax = axes[i]
    grp.plot.scatter('x', 'y', ax=ax)
    grp.apply(annotate, ax=ax, axis=1)
fig.tight_layout()

enter image description here

设置

label = ('A' , 'D' , 'K', 'L', 'P')
x = (1 , 4 , 9, 6, 4)
y = (2 , 6 , 5, 8, 9)
plot_id = (1 , 1 , 2, 2, 3)

df = pd.DataFrame(dict(label=label, x=x, y=y, plot_id=plot_id))

答案 1 :(得分:1)

这是解决问题的简单方法

zipped = zip(zip(zip(df.x, df.y), df.plot_id), df.label)
# Result : [(((1, 2), 1), 'A'),
#           (((4, 6), 1), 'D'),
#           (((9, 5), 2), 'K'),
#           (((6, 8), 2), 'L'),
#           (((4, 9), 3), 'P')]

要检索位置,绘图索引和标签,您可以循环如下:

for (pos, plot), label in zipped:
    ...
    print pos
    print plot
    print label

现在就是你可以做的事情:

import matplotlib.pyplot as plt

for (pos, plot), label in zipped:
    plt.figure(plot)
    x, y = pos
    plt.scatter(x, y)
    plt.annotate(label, xy=pos)

它将创建与plot_ids一样多的数字,并且每个数字显示具有相应plot_ids值的点的散点图。更重要的是它在每个点上覆盖了标签。