从 Pandas DataFrame 绘图时注释数据点
Posted
技术标签:
【中文标题】从 Pandas DataFrame 绘图时注释数据点【英文标题】:Annotate data points while plotting from Pandas DataFrame 【发布时间】:2013-04-01 08:38:25 【问题描述】:我想在图上的点旁边用它们的值来注释数据点。我发现的示例仅将 x 和 y 作为向量处理。但是,我想对包含多列的 pandas DataFrame 执行此操作。
ax = plt.figure().add_subplot(1, 1, 1)
df.plot(ax = ax)
plt.show()
为多列 DataFrame 注释所有点的最佳方法是什么?
【问题讨论】:
【参考方案1】:这是Dan Allan's answer 的一个(非常)简洁的版本:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import string
df = pd.DataFrame('x':np.random.rand(10), 'y':np.random.rand(10),
index=list(string.ascii_lowercase[:10]))
这给出了:
x y
a 0.541974 0.042185
b 0.036188 0.775425
c 0.950099 0.888305
d 0.739367 0.638368
e 0.739910 0.596037
f 0.974529 0.111819
g 0.640637 0.161805
h 0.554600 0.172221
i 0.718941 0.192932
j 0.447242 0.172469
然后:
fig, ax = plt.subplots()
df.plot('x', 'y', kind='scatter', ax=ax)
for k, v in df.iterrows():
ax.annotate(k, v)
最后,如果您处于交互模式,您可能需要刷新绘图:
fig.canvas.draw()
产生:
或者,因为这看起来非常难看,你可以很容易地美化一些东西:
from matplotlib import cm
cmap = cm.get_cmap('Spectral')
df.plot('x', 'y', kind='scatter', ax=ax, s=120, linewidth=0,
c=range(len(df)), colormap=cmap)
for k, v in df.iterrows():
ax.annotate(k, v,
xytext=(10,-5), textcoords='offset points',
family='sans-serif', fontsize=18, color='darkslategrey')
看起来好多了:
【讨论】:
漂亮! (你说的第二个情节......) @LondonRob,有没有你能告诉我我们如何才能只对其他第 n 个标记进行注释? @st19297 创建一个新问题!并包含指向此答案的链接(请参阅“分享”链接),以便人们知道您从哪里开始! 我使用这种方法遇到的问题是,如果标签超出绘图区域,它们会被截断。知道如何解决这个问题吗? @HowardLovatt,您可以使用xlim=[0,1]
和ax.set(xlim=xlim, ylim=ylim)
重置轴限制,如果您需要动态计算限制,您可以从df[x].max()
开始并通过乘以0.9
进行调整或者1.1
,比如说。【参考方案2】:
您想使用其他列之一作为注释的文本吗?这是我最近做的。
从一些示例数据开始
In [1]: df
Out[1]:
x y val
0 -1.015235 0.840049 a
1 -0.427016 0.880745 b
2 0.744470 -0.401485 c
3 1.334952 -0.708141 d
4 0.127634 -1.335107 e
绘制点。在本例中,我将 y 与 x 绘制成图。
ax = df.set_index('x')['y'].plot(style='o')
编写一个循环遍历 x、y 和要在该点旁边注释的值的函数。
def label_point(x, y, val, ax):
a = pd.concat('x': x, 'y': y, 'val': val, axis=1)
for i, point in a.iterrows():
ax.text(point['x'], point['y'], str(point['val']))
label_point(df.x, df.y, df.val, ax)
draw()
【讨论】:
【参考方案3】:假设您的df
有多个列,其中三个是x
、y
和lbl
。要使用lbl
注释您的(x,y)
散点图,只需:
ax = df.plot(kind='scatter',x='x',y='y')
df[['x','y','lbl']].apply(lambda row: ax.text(*row),axis=1);
【讨论】:
对于第一行,当前的 pandas 将使用 df.plot('x', 'y', kind='scatter')【参考方案4】:我发现以前的答案很有帮助,尤其是LondonRob's example,它稍微改进了布局。
唯一困扰我的是,我不喜欢从 DataFrame 中提取数据然后循环遍历它们。似乎浪费了DataFrame。
这是一个替代方案,它使用 .apply() 避免循环,并包含更好看的注释(我认为色阶有点过分,无法让颜色条消失):
ax = df.plot('x', 'y', kind='scatter', s=50 )
def annotate_df(row):
ax.annotate(row.name, row.values,
xytext=(10,-5),
textcoords='offset points',
size=18,
color='darkslategrey')
_ = df.apply(annotate_df, axis=1)
编辑备注
我最近编辑了我的代码示例。最初它使用相同的:
fig, ax = plt.subplots()
作为其他暴露轴的帖子,但是这是不必要的,并且使:
import matplotlib.pyplot as plt
线也不需要。
另请注意:
如果您尝试重现此示例,并且您的绘图中的点与我们的绘图不同,可能是因为 DataFrame 使用了随机值。如果我们使用固定数据表或随机种子,它可能不会那么混乱。 根据分数,您可能必须使用xytext
值才能获得更好的展示位置。
【讨论】:
以上是关于从 Pandas DataFrame 绘图时注释数据点的主要内容,如果未能解决你的问题,请参考以下文章