python - 在每个单元格中创建具有相同点数的 2D Hist
问题描述
我正在寻找一种可能性来创建具有不规则bin 大小的 2D 直方图,并可以将热量绘制为 z 变量。
数据:我有十亿个对象。每个对象都有特征 x、y 和 z 的异常分数。
绘图:绘制的是所有带有 y 对 x 的对象。直方图应该具有不规则(自适应)的 bin 大小,以便在创建的每个 bin 中都有相同数量的对象。这应该最初创建一个没有任何可见特征的直方图,只有一种颜色(颜色代表对象的数量)。
为了创建 bin 边缘,我首先使用 np.percentiles 并将基于 x 特征的对象分成百分位数。其次,我使用第一个 x binedge,找到其中的所有点并根据百分位数在 y 方向上对它们进行 binedge。这看起来像这样(伪代码):
for i, key_x in enumerate(np.percentile(x, np.arange(0,101, 10))):
xedges[i] = key_x
objects = find_all_objects_within_binedge(key_x)
for j, key_y in enumerate(np.percentile(objects["y"], np.arange(0,101, 10))):
yedges[i, j] = key_y
所以 xedges 是一个在 x 方向上有边的数组,而 yedges 是一个矩阵,为我提供了每个 x 边的 y 边。如果这不能理解,请告诉我。
因此,如果我们想象会产生的直方图,我们将在 x 中有直线分箱线。但在 y 方向上,这些线将被分割。请参阅此处以了解我的意思是 y bin 是不规则拆分。
这就是我被卡住了。我不知道如何使用这些不规则的 bin 从我的 x-binedges 和 y-binedges 创建直方图或绘图。
目标(为了更好地理解):一旦完成,我希望能够使用 z 值将每个 bin 用该单元格内所有点的平均值或标准着色(准备好代码)。理想情况下,这看起来也很顺利,除了一些小的例外,这将是异常的,也是我正在寻找的。但这对于 plt.pcolormesh 应该是可行的。
英语不是我的母语,我尽力描述这个问题。如果有不清楚的地方,请告诉我,我会尽力澄清。提前谢谢你们:)
解决方案
似乎这个问题要求一种在网格上绘制值的方法,该网格在一个维度上是规则的,但在另一个维度上是不规则的。
据我了解,这样的网格将由例如 x 方向的一维数组和 y 方向的二维数组定义。两个数组都将表示相应维度中网格单元的边缘。
对于 M x N 网格,x_edges
因此将具有N+1
元素,并且y_edges
形状为(M+1, N)
。下面是一个 4 x 3 的网格。
x_edges = np.array([0,1,2,3])
y_edges = np.array([[0.,0.,0.],
[.3,.2,.2],
[.5,.6,.4],
[.8,.9,.7],
[1.,1.,1.]])
通常的 matplotlib 工具喜欢imshow
或pcolor
做 - 据我所知 - 不允许绘制这样的网格。因此,另一种方法是使用 aPolyCollection
并用它绘制相应的矩形。
可以将应映射到颜色的值数组设置为该集合。这个数组应该每个维度少一个值并且是平坦的,即有 M*N 个元素。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection
# Starting data: A grid, regular in x-direction and irregular in y direction.
x_edges = np.array([0,1,2,3])
y_edges = np.array([[0.,0.,0.],
[.3,.2,.2],
[.5,.6,.4],
[.8,.9,.7],
[1.,1.,1.]])
######## Grid creation ################
#y_edges = np.concatenate((y_edges, np.zeros(len(y_edges))))
s = np.array(y_edges.shape)
# make x_edges 2D as well.
x_edges = np.tile(x_edges, s[0]-1).reshape((s[0]-1, s[1]+1))
# you may also have an array of values.
# This should be of shape one less than the edges and flattened.
values = np.arange(np.prod(s+np.array((-1,0))))
# Produce a vertices array of the edges of rectangles that form each pixel.
x = np.c_[x_edges[:,:-1].flatten(), x_edges[:,:-1].flatten(),
x_edges[:,1: ].flatten(), x_edges[:,1: ].flatten()]
y = np.c_[y_edges[:-1,:].flatten(), y_edges[1: ,:].flatten(),
y_edges[1: ,:].flatten(), y_edges[:-1,:].flatten()]
xy = np.stack((x,y), axis=2)
# Create collection of rectangles.
pc = PolyCollection(xy, closed=True, edgecolors="k", linewidth=0.72, cmap="inferno")
pc.set_array(values)
######## Plotting ################
fig, ax = plt.subplots()
ax.add_collection(pc)
fig.colorbar(pc, ax=ax)
ax.margins(0)
ax.autoscale()
plt.show()
此网格使用少量单元格来显示原理。如果您想要更多单元格,请确保不要通过删除edgecolors
和linewidth
参数来绘制矩形的边缘。
推荐阅读
- angular - 如何将 datepicker 绑定到 ngmodel
- azure-data-factory - ADF IF 条件 - 计算源列
- hibernate - QueryDSL 和多对多关系
- linux - New-PSSession:此参数集需要 WSMan,未找到支持的 WSMan 客户端库。CENTOS/RHEL 8
- c - 可以想象,严格按照C11(或以上)标准的规定,这个程序可以优化打印hello吗?
- amazon-web-services - React native 应该如何处理异步无服务器图像处理管道以将文本传递回移动应用程序
- mongodb - Mongodb:获取所有列的不同记录,并同时针对另一列连接值
- redis - 是否可以定义仅适用于部分键的 LRU Redis
- asp.net-core - 由于错误“错误:传输出现错误”,SignalR HubConnection 未能成功启动。
- node.js - 添加自定义 ckeditor5 在线构建时,npm 构建失败