【问题标题】:How to label data points in matplotlib scatter plot while looping through pandas dataframes?循环遍历熊猫数据框时如何在matplotlib散点图中标记数据点?
【发布时间】:2017-04-20 03:04:00
【问题描述】:

我有一个包含以下列的 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 循环。但我不知道如何将两者结合起来。

我希望我可以发布更好的代码 sn-p 到目前为止我所做的 - 但这太糟糕了。这里是:

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

这就是我得到的 - 不幸的是。关于如何进行的任何想法?

【问题讨论】:

  • plot_idlabel 之间的联系是什么?
  • 抱歉,我在评论时编辑了问题。我基本上是在尝试为每个人制作 3 个地块 plot_id
  • 那么label 列是没用的...
  • 没有。我想用label标记/注释数据条目(或字形,如果你愿意的话)。
  • 您需要非常精确地了解以下内容:您要创建多少个地块?你希望每个地块有多少分?标签应该出现在图中的什么位置?您希望每个图只有一个点是否正确?

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


【解决方案1】:

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

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

2.png

3.png

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

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()

设置

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))

【讨论】:

  • 因为有 54 个plot_ids,我认为子图可能不是一个好主意。我错了吗?
  • 对不起,你没说清楚。你说你想要单独的情节。
  • 是的,确实如此。我需要 54 个单独的地块。下次我会尽量说清楚!
  • 很好的解决方案!谢谢!
【解决方案2】:

这是处理您的问题的简单方法

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 值的点的散点图。更重要的是它覆盖了每个点的标签。

【讨论】:

  • 哇!这很棒!有没有办法保存循环上的图?我试图修改代码并保存,但不幸的是也替换了......
  • 我得到每个 pos 的数字。因此,鉴于提出的示例,我得到了 6 个数字。如何将它们组合成 3 个?
  • @Rachel 你确定你得到每个pos 的数字吗?它非常适合我......
  • 是的。您的打印命令建议您使用 Python 2 而我使用 python 3?也许这就是原因?
  • 你能用你的新代码和你使用的变量来编辑你的问题吗?我去看看
猜你喜欢
  • 2020-11-20
  • 2017-06-08
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2017-05-07
相关资源
最近更新 更多