Matplotlib中的散点图轮廓

ast*_*max 12 python matplotlib scatter-plot contour

我有一个庞大的散点图(~100,000点),我在matplotlib中生成.每个点在此x/y空间中都有一个位置,我想生成包含总点数的某些百分位数的轮廓.

matplotlib中是否有一个函数可以执行此操作?我已经研究过contour(),但是我必须用这种方式编写自己的函数.

谢谢!

Joe*_*ton 44

基本上,你想要某种密度估计.有多种方法可以做到这一点:

  1. 使用某种2D直方图(例如matplotlib.pyplot.hist2dmatplotlib.pyplot.hexbin)(您也可以将结果显示为轮廓 - 只需使用numpy.histogram2d然后对结果数组进行轮廓处理.)

  2. 进行核密度估计(KDE)并对结果进行轮廓分析.KDE本质上是一个平滑的直方图.它不是落入特定箱子中的一个点,而是为周围的箱子增加一个重量(通常是高斯"钟形曲线"的形状).

使用2D直方图简单易懂,但有趣的是给出了"块状"结果.

第二个"正确"地做一些皱纹(即没有一个正确的方法).我不会在这里详细介绍,但如果你想统计解释结果,你需要阅读它(特别是带宽选择).

无论如何,这是差异的一个例子.我将以相似的方式绘制每一个,所以我不会使用轮廓,但您可以使用等高线图轻松绘制2D直方图或高斯KDE:

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde

np.random.seed(1977)

# Generate 200 correlated x,y points
data = np.random.multivariate_normal([0, 0], [[1, 0.5], [0.5, 3]], 200)
x, y = data.T

nbins = 20

fig, axes = plt.subplots(ncols=2, nrows=2, sharex=True, sharey=True)

axes[0, 0].set_title('Scatterplot')
axes[0, 0].plot(x, y, 'ko')

axes[0, 1].set_title('Hexbin plot')
axes[0, 1].hexbin(x, y, gridsize=nbins)

axes[1, 0].set_title('2D Histogram')
axes[1, 0].hist2d(x, y, bins=nbins)

# Evaluate a gaussian kde on a regular grid of nbins x nbins over data extents
k = kde.gaussian_kde(data.T)
xi, yi = np.mgrid[x.min():x.max():nbins*1j, y.min():y.max():nbins*1j]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))

axes[1, 1].set_title('Gaussian KDE')
axes[1, 1].pcolormesh(xi, yi, zi.reshape(xi.shape))

fig.tight_layout()
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

一个警告:如果点数非常多,scipy.stats.gaussian_kde将会变得非常缓慢.通过近似来加速它是相当容易的 - 只需采用2D直方图并使用右半径和协方差的高斯滤波器对其进行模糊处理.如果你愿意,我可举个例子.

另一个警告:如果你在非笛卡尔坐标系中这样做,这些方法都不适用!在球壳上获得密度估计有点复杂.

  • 抱歉耽搁了!基本上,是的,您应该调整轮廓水平以反映百分比.`gaussian_kde`结果是概率密度函数的估计(PDF).因此,将值修正为0.1意味着90%的数据位于轮廓内等.对于2D直方图,这些值是原始计数,因此您需要进行标准化.希望这有助于澄清一些事情. (2认同)