如何在稀疏散点图中添加点的计数作为标签

时间:2017-04-21 09:30:34

标签: python matplotlib plot plotly

我有稀疏的散点图来显示预测值与实际值的比较。值的范围是1-4,没有小数点。

到目前为止,我已尝试plotly使用hte代码(但我也可以使用 matplotlib 解决方案):

my_scatter = go.Scatter(
    x = y_actual, y = y_pred, mode = 'markers', 
    marker = dict(color = 'rgb(240, 189, 89)', opacity=0.5)
)   

这可以很好地打印图表(见下文)。我使用不透明度来查看每个点的密度。即如果两个点位于彼此之上,则该点将以较暗的颜色显示。但是,这还不够明确。是否可以将每个点的计数添加为标签?某些交叉路口有一些重叠。我想显示有多少点相交。可以使用 matplotlib plotly 自动完成吗?

enter image description here

1 个答案:

答案 0 :(得分:2)

这个答案使用了matplotlib。

首先回答最初的问题:您需要找出数据在给定坐标处产生点的频率,以便能够对点进行注释。如果所有值都是整数,则可以使用2d直方图轻松完成。在hstogram之外,然后只选择那些计数值非零的二进制位并在一个循环中注释相应的值:

x = [3, 0, 1, 2, 2, 0, 1, 3, 3, 3, 4, 1, 4, 3, 0]
y = [1, 0, 4, 3, 2, 1, 4, 0, 3, 0, 4, 2, 3, 3, 1]

import matplotlib.pyplot as plt
import numpy as np

x = np.array(x)
y = np.array(y)

hist, xbins,ybins = np.histogram2d(y,x, bins=range(6))
X,Y = np.meshgrid(xbins[:-1], ybins[:-1])
X = X[hist != 0]; Y = Y[hist != 0]
Z   = hist[hist != 0]


fig, ax = plt.subplots()
ax.scatter(x,y, s=49, alpha=0.4)

for i in range(len(Z)):
    ax.annotate(str(int(Z[i])), xy=(X[i],Y[i]), xytext=(4,0), 
                textcoords="offset points" )

plt.show()

enter image description here

然后您可以决定不绘制所有点,但直方图的结果可以改变散点的颜色和大小,

ax.scatter(X,Y, s=(Z*20)**1.4, c = Z/Z.max(), cmap="winter_r", alpha=0.4)

enter image description here

由于所有值都是整数,您也可以选择图像图,

fig, ax = plt.subplots()
ax.imshow(hist, cmap="PuRd")

for i in range(len(Z)):
    ax.annotate(str(int(Z[i])), xy=(X[i],Y[i]), xytext=(0,0), color="w",
                ha="center", va="center", textcoords="offset points" )

enter image description here

如果没有计算出现次数的必要性,另一个选择是使用hexbin图。这给出了六角形分组中点的略微不准确的位置,但我仍然想提到这个选项。

import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np

x = np.array(x)
y = np.array(y)

fig, ax = plt.subplots()

cmap = plt.cm.PuRd
cmaplist = [cmap(i) for i in range(cmap.N)]
cmaplist[0] = (1.0,1.0,1.0,1.0)
cmap = matplotlib.colors.LinearSegmentedColormap.from_list('mcm',cmaplist, cmap.N)

ax.hexbin(x,y, gridsize=20, cmap=cmap, linewidth=0 )

plt.show()

enter image description here