如何在Matplotlib中调试散点图?

3

我有以下数据框:

df = pd.DataFrame([
    ['A', 'X', '2020-10-01', 1],
    ['A', 'X', '2020-10-02', 2], 
    ['A', 'X', '2020-10-03', 3], 
    ['A', 'Y', '2020-10-01', 4],
    ['A', 'Y', '2020-10-02', 5], 
    ['A', 'Y', '2020-10-03', 6],
    ['B', 'Z', '2020-10-01', 7],
    ['B', 'Z', '2020-10-02', 8], 
    ['B', 'Z', '2020-10-03', 9], 
    ['B', 'Z', '2020-10-01', 10],
    ['B', 'Z', '2020-10-02', 11], 
    ['B', 'Z', '2020-10-03', 12],    
],
    columns=['Q', 'W', 'DT', 'V']
)

我想创建一个散点图:

fig, ax = plt.subplots(figsize=(12, 8), frameon=False)
fig.suptitle('Plotz', fontsize=16)
ax.set_title('DF Plot')
ax.scatter(x=df.DT, y=df.W, s=df.V)

这创建了下面的图表:

enter image description here

我想找出实际发生了什么,因为图表上有9个数据点,而数据中有12个数据点。注释图表不起作用,因为它会在顶部行注释两个值。
for i, txt in enumerate(df.V):
    ax.annotate(txt, (df.DT[i], df.W[i]), fontsize=14)

有没有一种方法可以在 x,y 值对有多个值的情况下找出发生了什么(就像这种情况)?

更新:也许我表述不清楚。在这种情况下,Matplotlib 的默认行为是什么?是最后一个值胜出吗?如何在图上显示实际值?(与显示两个值的注释代码不同,它显示真实值)。

在更多的谷歌搜索后,我认为答案是:

用 Matplotlib 可视化具有重叠点的散点图


2
Z 点重叠。 - CDJB
1
这是因为您的Z值是重复的。所以在6个Z值中,您只得到3个。 - Sheldore
是的,会发生什么?更大的值获胜,最后一个值获胜吗?是否计算平均值?当存在重叠值时,默认行为是什么?我能控制这种行为吗? - Istvan
1个回答

5
通常情况下,点会按照遇到的顺序绘制在彼此之上。如果没有透明度,则最后一个绘制的点将可见,而先前的点仅在它们较大时显示一些边框。

因此,调试这种情况的一种方法是设置 alpha 值使点变得透明。多个重叠的点会显示更暗并具有一些边框。
使用给定的测试数据,以下代码扩大了点的大小并设置了 alpha。由于点的大小变得极大,需要调整轴限制。使用多种颜色将更加强调重叠。
ax.scatter(x=df.DT, y=df.W, s=df.V*150, alpha=0.4)
plt.xlim(-1,3)
plt.ylim(-1,3)

resulting plot

另一种方法是添加抖动:在每个点的位置上添加一些小的随机噪声。对于数值数据,可以直接将抖动添加到数据中。对于分类数据,在调用 scatter 后可以修改位置:

import numpy as np
dots = ax.scatter(x=df.DT, y=df.W, s=df.V)
offsets =  dots.get_offsets()
jittered_offsets = offsets + np.random.uniform(-0.1, 0.1, offsets.shape)
dots.set_offsets(jittered_offsets)

如果保留原始颜色和大小,并去除透明度,这将明显吸引重叠点的注意力: 抖动图

如果两个轴都是分类变量,则另一种方法是基于位置进行计数,并圈出出现多次的位置:

import collections
dots = ax.scatter(x=df.DT, y=df.W, s=df.V)
offsets =  dots.get_offsets()
counts = collections.Counter([(x,y)  for x, y in offsets])
suspects = [p for p in counts if counts[p] >= 2]
ax.scatter([x for x, _ in suspects], [y for _, y in suspects], ec='crimson', lw=1, fc='none', s=50)

encercled plot

当然,不同的方法(alpha、颜色、抖动、环绕)可以根据实际数据的具体情况进行组合。

谢谢您这个惊人的答案!我刚刚实现了抖动的方式,而且它运行得非常好。 - Istvan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接