Python 散点图 - 重叠数据
Python Scatter Plot - Overlapping data
我有一个散点图,但很多时候值可以在同一个点上,我已经使用颜色和 alpha 来尝试补救这种情况。然而,如您所见,仍然很难区分某些区域中绘制的内容。
有没有更简单的方法解决这个问题?
谢谢
您可以抖动这些值(添加一些随机噪声),这样它们就不会完全位于同一点。
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randint(low=1,high=5,size=50)
y = np.random.randint(low=0,high=2,size=50)
jittered_y = y + 0.1 * np.random.rand(len(y)) -0.05
jittered_x = x + 0.1 * np.random.rand(len(x)) -0.05
plt.figure(figsize=(10,5))
plt.subplot(221)
plt.scatter(x,y,s=10,alpha=0.5)
plt.title('No Jitter')
plt.subplot(222)
plt.scatter(x,jittered_y,s=10,alpha=0.5)
plt.title('Y Jittered')
plt.subplot(223)
plt.scatter(jittered_x,y,s=10,alpha=0.5)
plt.title('X Jittered')
plt.subplot(224)
plt.scatter(jittered_x,jittered_y,s=10,alpha=0.5)
plt.title('Y and X Jittered')
plt.tight_layout();
如果您想要确定性偏移量,我制作此函数是为了解决类似的问题(让我来到这里寻求答案)。
请注意,此功能仅适用于完全重叠的点。但是,您很可能会四舍五入您的观点并稍微修改此函数以适应“足够接近”的观点。
希望这对您有所帮助。
import numpy as np
def dodge_points(points, component_index, offset):
"""Dodge every point by a multiplicative offset (multiplier is based on frequency of appearance)
Args:
points (array-like (2D)): Array containing the points
component_index (int): Index / column on which the offset will be applied
offset (float): Offset amount. Effective offset for each point is `index of appearance` * offset
Returns:
array-like (2D): Dodged points
"""
# Extract uniques points so we can map an offset for each
uniques, inv, counts = np.unique(
points, return_inverse=True, return_counts=True, axis=0
)
for i, num_identical in enumerate(counts):
# Prepare dodge values
dodge_values = np.array([offset * i for i in range(num_identical)])
# Find where the dodge values must be applied, in order
points_loc = np.where(inv == i)[0]
#Apply the dodge values
points[points_loc, component_index] += dodge_values
return points
这里是之前和之后的例子。
之前:
之后:
此方法仅适用于完全重叠的点(或者如果您愿意以 np.unique
找到匹配点的方式舍入点)。
我有一个散点图,但很多时候值可以在同一个点上,我已经使用颜色和 alpha 来尝试补救这种情况。然而,如您所见,仍然很难区分某些区域中绘制的内容。
有没有更简单的方法解决这个问题?
谢谢
您可以抖动这些值(添加一些随机噪声),这样它们就不会完全位于同一点。
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randint(low=1,high=5,size=50)
y = np.random.randint(low=0,high=2,size=50)
jittered_y = y + 0.1 * np.random.rand(len(y)) -0.05
jittered_x = x + 0.1 * np.random.rand(len(x)) -0.05
plt.figure(figsize=(10,5))
plt.subplot(221)
plt.scatter(x,y,s=10,alpha=0.5)
plt.title('No Jitter')
plt.subplot(222)
plt.scatter(x,jittered_y,s=10,alpha=0.5)
plt.title('Y Jittered')
plt.subplot(223)
plt.scatter(jittered_x,y,s=10,alpha=0.5)
plt.title('X Jittered')
plt.subplot(224)
plt.scatter(jittered_x,jittered_y,s=10,alpha=0.5)
plt.title('Y and X Jittered')
plt.tight_layout();
如果您想要确定性偏移量,我制作此函数是为了解决类似的问题(让我来到这里寻求答案)。 请注意,此功能仅适用于完全重叠的点。但是,您很可能会四舍五入您的观点并稍微修改此函数以适应“足够接近”的观点。
希望这对您有所帮助。
import numpy as np
def dodge_points(points, component_index, offset):
"""Dodge every point by a multiplicative offset (multiplier is based on frequency of appearance)
Args:
points (array-like (2D)): Array containing the points
component_index (int): Index / column on which the offset will be applied
offset (float): Offset amount. Effective offset for each point is `index of appearance` * offset
Returns:
array-like (2D): Dodged points
"""
# Extract uniques points so we can map an offset for each
uniques, inv, counts = np.unique(
points, return_inverse=True, return_counts=True, axis=0
)
for i, num_identical in enumerate(counts):
# Prepare dodge values
dodge_values = np.array([offset * i for i in range(num_identical)])
# Find where the dodge values must be applied, in order
points_loc = np.where(inv == i)[0]
#Apply the dodge values
points[points_loc, component_index] += dodge_values
return points
这里是之前和之后的例子。
之前:
之后:
此方法仅适用于完全重叠的点(或者如果您愿意以 np.unique
找到匹配点的方式舍入点)。