matplotlib 中具有重叠点的散点图的可视化
Posted
技术标签:
【中文标题】matplotlib 中具有重叠点的散点图的可视化【英文标题】:Visualization of scatter plots with overlapping points in matplotlib 【发布时间】:2013-10-04 13:52:25 【问题描述】:我必须在 matplotlib 的散点图中表示大约 30,000 个点。这些点属于两个不同的类,所以我想用不同的颜色来描绘它们。
我成功了,但是有一个问题。这些点在许多区域中重叠,我最后描述的类将在另一个之上可视化,隐藏它。此外,散点图无法显示每个区域中有多少点。 我也试过用 histogram2d 和 imshow 制作一个二维直方图,但是很难清楚地显示属于这两个类的点。
您能否提出一种方法来明确类别的分布和点的集中度?
编辑:为了更清楚,这是 link 到我的数据文件中,格式为“x,y,class”
【问题讨论】:
为什么不用两种颜色的直方图?看起来还不够好吗? @OfirIsrael 我曾尝试使用 histogram2d 和 imshow 与 alpha 水平有两个重叠的直方图,但结果似乎很差 您是否尝试过使用轮廓而不是 alpha 混合来显示直方图? matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.contour 不要在您的数据中添加噪音,这会越界进入不道德的数据操作。 @tcaswell 当且仅当你隐藏它时,它才会越界进入不道德的数据操作。 【参考方案1】:一种方法是将数据绘制为 低 alpha 散点图,这样您就可以看到各个点以及粗略的密度测量。 (这样做的缺点是该方法可以显示的重叠范围有限 - 即最大密度约为 1/alpha。)
这是一个例子:
您可以想象,由于可以表达的重叠范围有限,因此需要在各个点的可见性和重叠量的表达(以及标记、绘图等的大小)之间进行权衡。
import numpy as np
import matplotlib.pyplot as plt
N = 10000
mean = [0, 0]
cov = [[2, 2], [0, 2]]
x,y = np.random.multivariate_normal(mean, cov, N).T
plt.scatter(x, y, s=70, alpha=0.03)
plt.ylim((-5, 5))
plt.xlim((-5, 5))
plt.show()
(我在这里假设您的意思是 30e3 点,而不是 30e6。对于 30e6,我认为需要某种类型的平均密度图。)
【讨论】:
【参考方案2】:您还可以通过首先计算散点分布的核密度估计,然后使用密度值为散点的每个点指定颜色来为点着色。修改前面示例中的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde as kde
from matplotlib.colors import Normalize
from matplotlib import cm
N = 10000
mean = [0,0]
cov = [[2,2],[0,2]]
samples = np.random.multivariate_normal(mean,cov,N).T
densObj = kde( samples )
def makeColours( vals ):
colours = np.zeros( (len(vals),3) )
norm = Normalize( vmin=vals.min(), vmax=vals.max() )
#Can put any colormap you like here.
colours = [cm.ScalarMappable( norm=norm, cmap='jet').to_rgba( val ) for val in vals]
return colours
colours = makeColours( densObj.evaluate( samples ) )
plt.scatter( samples[0], samples[1], color=colours )
plt.show()
前段时间,当我注意到 scatter 函数的文档时,我学会了这个技巧 --
c : color or sequence of color, optional, default : 'b'
c
可以是单个颜色格式字符串,也可以是长度为N
的颜色规范序列,或者是使用cmap
和norm
指定的要映射到颜色的N
数字序列kwargs(见下文)。请注意,c
不应是单个数字 RGB 或 RGBA 序列,因为它与要进行颜色映射的值数组无法区分。c
可以是二维数组,其中行是 RGB 或 RGBA,但是,包括为所有点指定相同颜色的单行的情况。
【讨论】:
对于绘制大型数据集时最常遇到的问题之一,这是一个令人惊叹的解决方案。干得好! 有没有什么办法可以在上图中加一个颜色条来表示每种颜色的密度? 您可以通过简单地使用 scatter 方法的cmap
kwarg 来优化此解决方案(即plt.scatter(samples[0], samples[1], c=densObj.evaluate(samples), cmap="jet")
,无需额外的功能。
@ZackEriksen 试试plt.colorbar()
【参考方案3】:
我的回答可能无法完美回答您的问题,但是,我也尝试绘制重叠点,但我的完全重叠。因此我想出了这个函数来抵消相同的点。
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
找到匹配点的方式对点进行四舍五入)。
【讨论】:
以上是关于matplotlib 中具有重叠点的散点图的可视化的主要内容,如果未能解决你的问题,请参考以下文章
Python使用matplotlib可视化散点图使用seaborn中的lmplot函数使用多子图可视化不同分组的散点图最优拟合线性回归曲线