pandas kdeplut设定点标记

velaa5lx  于 2023-04-28  发布在  其他
关注(0)|答案(2)|浏览(111)

我正在尝试这样做(Draw a point at the mean peak of a distplot or kdeplot in Seaborn)。我需要标记值为13.72的点。
但是:列表索引超出范围
string:x = ax.lines[0].get_xdata()

int_rate = df['int_rate']
ax = sns.kdeplot(int_rate, shade = True)

x = ax.lines[0].get_xdata()
y = ax.lines[0].get_ydata()
maxid = np.where(x == 13.72)
plt.plot(x[maxid],y[maxid], 'bo', ms=10)
dxxyhpgq

dxxyhpgq1#

问题是设置shading = True seaborn绘制的是matplotlib.PolyCollection而不是matplotlib.lines.Line2D对象,因此ax.lines是一个空列表(ax不包含任何行)。
您可以将着色设置为False并遵循给定的示例,它将起作用,或者如果您希望保留着色并仍然通过访问该点的坐标来绘制最高点,则需要从PolyCollection对象获取它。
根据this stackoverflow question,您可以通过PolyCollection的get_paths()方法执行此操作。
如果替换代码:

x = ax.lines[0].get_xdata()
y = ax.lines[0].get_ydata()
maxid = np.where(x == 13.72)
plt.plot(x[maxid],y[maxid], 'bo', ms=10)

其中:

x, y = ax.get_children()[0].get_paths()[0].vertices.T
maxid = y.argmax()
plt.plot(x[maxid], y[maxid], 'bo', ms=10)

您将得到带有阴影的KDE图,其中标记了最高点:

  • 注:使用的数据是来自seaborn的tips数据集。*
    **编辑:**由于您需要标记特定的x值,而PolyCollection.get_paths()ax.lines[0].get_xdata()不一定会返回所绘制的数据集中包含的精确x值,因此您可能希望在查找np.where(np.round(x,2) == 13.72)索引之前尝试对这些数组进行舍入
ncgqoxb0

ncgqoxb02#

100年后。实际上找到了一种方法,有点笨拙,但它有效。因为它是一个分布,点并不完全匹配。但为了绘图,你可以找到最近的点:

import numpy as np
def find_nearest(array, value):
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return array[idx]

然后你会在直线中找到离那个True X最近的点。为了绘图的目的,它应该足够近:

int_rate = df['int_rate']
ax = sns.kdeplot(int_rate, shade = True)

x = ax.lines[0].get_xdata()
y = ax.lines[0].get_ydata()

points = list(zip(x, y))
t_dic = dict(points)

true_x = 13.72

x_point = find_nearest(np.array(list(t_dic.keys())), true_x)

sns.scatterplot(x = [x_point],
                y = [t_dic[x_point]])

相关问题