我正在寻找一种创建具有不规则 bin大小的2D直方图的可能性,并可能将热量绘制为z变量。
数据:我有十亿个对象。每个对象都具有特征x,y和z的异常分数。
图:绘制的是所有y对x的对象。直方图应具有不规则的(自适应)容器大小,以便在创建的每个容器中都放置相同的 amount 对象。首先应该创建一个没有任何可见特征的直方图,只有一种颜色(颜色代表对象的数量)。
要创建bin边缘,我首先使用np.percentiles并将基于x特征的对象分离为百分位数。其次,我使用第一个x binedge,找到其中的所有点,然后根据百分位数在y方向上将它们分类。看起来像这样(伪代码):
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方向上具有binedges的数组,而yedges是一个矩阵,为我提供了每个x binedge的y binedges。如果无法理解,请告诉我。
因此,如果我们想象将要产生的直方图,我们将在x中具有直线装仓线。但是在y方向上,这些线将被分开。请参阅here来了解y箱不规则拆分的含义。
这是我被困住的地方。我不知道如何使用这些不规则的箱从我的x-binedges和y-binedges创建直方图或绘图。
目标(更好地理解): 一旦完成,我希望能够使用z值使该单元格由该单元格内所有点的均值或标准差着色(准备好了代码)。理想情况下,这看起来也非常平滑,除了一些小例外,这是异常的,也是我要寻找的东西。但这对于plt.pcolormesh应该是可行的。
英语不是我的母语,所以我尽力描述了问题。如果有不清楚的地方,请告诉我,我会尽力澄清。预先谢谢你们:)
答案 0 :(得分:1)
据我了解,您希望根据仓中等量的数据对数据进行仓化。实际上,百分位数可用于此目的。如果使用numpy,则可以沿d维执行此操作。这是2d分箱的示例:
import matplotlib.pyplot as plt
from numpy import array, random, percentile
data = random.randn(1000, 2)
data[:, 1] = data[:, 1] * .1 + 1 # shift the gauss
percentiles = percentile(data, range(0, 100, 10), axis = 0)
fig, ax = plt.subplots()
ax.hist2d(*data.T, bins = percentiles.T)
fig.show()
这是您要找的东西吗?
编辑: 非均匀网格示例
import matplotlib.pyplot as plt
from numpy import *
data = random.randn(1000, 2)
data[:, 1] = data[:, 1] * .1 + 1 # shift the gauss
xper = percentile(data[:, 0], range(0, 101, 10))
yper = zeros((xper.size, xper.size))
binnedData = ones(yper.shape)
for index, (binstart, binend) in enumerate(zip(xper[:-1], xper[1:])):
idx = where(logical_and(data[:, 0] >= binstart, data[:, 0] <= binend))[0] # expensive
yper[index] = percentile(data[idx, 1], range(0, 101, 10))
for jndex, j in enumerate(digitize(data[idx, 1], yper[index])):
j -= 1 #digit takes right bins
# generate dummy values
binnedData[index, j] += data[idx[j], :].sum() / xper.size
fig, ax = plt.subplots()
ax.pcolormesh(xper, yper, binnedData)
答案 1 :(得分:1)
这个问题似乎要求在网格上绘制值的方法,网格在一维上是规则的,而在另一维上是不规则的。
据我了解,这样的网格将由一维数组定义,例如x方向,以及y方向的2D数组。这两个阵列都将表示相应维度中的网格单元格的边缘。
对于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.]])
据我所知,像imshow
或pcolor
这样的常规matplotlib工具不允许绘制此类网格。因此,一种替代方法是使用PolyCollection
并绘制相应的矩形。
可以将应映射到颜色的值数组设置为该集合。此数组的每个尺寸应少一个值,并且应平坦,即具有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
参数来绘制矩形的边缘。