我是python的新手。
我有一个numpy矩阵,尺寸为42x42,其值在0-996范围内。我想用这个数据创建一个2D直方图。我一直在看教程,但它们似乎都展示了如何从随机数据而不是numpy矩阵创建2D直方图。
到目前为止,我已导入:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import colors
我不确定这些是否是正确的导入,我只是想从我看到的教程中学到一些东西。
我有numpy矩阵M
,其中包含所有值(如上所述)。最后,我希望它看起来像这样:
编辑:出于我的目的,使用matshow的 Hooked 的示例正是我正在寻找的。 p>
答案 0 :(得分:20)
如果你有来自计数的原始数据,你可以使用plt.hexbin
为你创建图(恕我直言这比方格更好):改编自hexbin
的例子:< / p>
import numpy as np
import matplotlib.pyplot as plt
n = 100000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
plt.hexbin(x,y)
plt.show()
如果您已经提到矩阵中的Z值,只需使用plt.imshow
或plt.matshow
:
XB = np.linspace(-1,1,20)
YB = np.linspace(-1,1,20)
X,Y = np.meshgrid(XB,YB)
Z = np.exp(-(X**2+Y**2))
plt.imshow(Z,interpolation='none')
答案 1 :(得分:12)
如果您不仅有2D直方图矩阵而且还有基础(x, y)
数据,那么您可以根据其中的分箱计数值制作(x, y)
点的散点图并为每个点着色。二维直方图矩阵:
import numpy as np
import matplotlib.pyplot as plt
n = 10000
x = np.random.standard_normal(n)
y = 2.0 + 3.0 * x + 4.0 * np.random.standard_normal(n)
xedges, yedges = np.linspace(-4, 4, 42), np.linspace(-25, 25, 42)
hist, xedges, yedges = np.histogram2d(x, y, (xedges, yedges))
xidx = np.clip(np.digitize(x, xedges), 0, hist.shape[0]-1)
yidx = np.clip(np.digitize(y, yedges), 0, hist.shape[1]-1)
c = hist[xidx, yidx]
plt.scatter(x, y, c=c)
plt.show()
答案 2 :(得分:1)
@unutbu's answer包含错误:xidx
和yidx
的计算方式错误(至少在我的数据样本中)。正确的方法应该是:
xidx = np.clip(np.digitize(x, xedges) - 1, 0, hist.shape[0] - 1)
yidx = np.clip(np.digitize(y, yedges) - 1, 0, hist.shape[1] - 1)
由于我们感兴趣的np.digitize
的返回维度介于1
和len(xedges) - 1
之间,但c = hist[xidx, yidx]
需要0
和{{之间的索引1}}。
以下是结果的比较。正如你所看到的那样,你会得到相似但不一样的结果。
hist.shape - 1
答案 3 :(得分:0)
我是“散布直方图”的忠实拥护者,但我认为其他解决方案不能完全使它们公正。 Here is a function来实现它们。与其他解决方案相比,此功能的主要优点是它按历史数据对点进行排序(请参见mode
参数)。这意味着结果看起来更像传统的直方图(即,您不会在不同的分箱中得到标记的混乱重叠)。
该数字的MCVE(使用my function):
import numpy as np
import matplotlib.pyplot as plt
from hist_scatter import scatter_hist2d
fig = plt.figure(figsize=[5, 4])
ax = plt.gca()
x = randgen.randn(npoint)
y = 2 + 3 * x + 4 * randgen.randn(npoint)
scat = scatter_hist2d(x, y,
bins=[np.linspace(-4, 4, 42),
np.linspace(-25, 25, 42)],
s=5,
cmap=plt.get_cmap('viridis'))
ax.axhline(0, color='k', linestyle='--', zorder=3, linewidth=0.5)
ax.axvline(0, color='k', linestyle='--', zorder=3, linewidth=0.5)
plt.colorbar(scat)
此方法的主要缺点是,最密集区域中的点与较低密度区域中的点重叠,从而导致每个存储箱区域的某种程度的歪曲。我花了很多时间探索两种解决方法:
1)将较小的标记用于较高密度的纸箱
2)对每个容器应用“剪贴”蒙版
第一个gives results太疯狂了。第二个看起来不错-尤其是如果您仅剪切具有~~ 20点的垃圾箱-但它非常慢(this figure花费了大约一分钟)。
因此,最终我决定,通过仔细选择标记大小和容器大小(s
和bins
),您可以获得视觉上令人愉悦的结果,就错误陈述数据而言,还不错。毕竟,这些2D直方图通常旨在作为基础数据的视觉辅助,而不是严格的定量表示。因此,我认为这种方法远远优于“传统2D直方图”(例如plt.hist2d
或plt.hexbin
),并且我认为,如果您找到此页面,则您也不喜欢传统(单色)散点图。
如果我是科学之王,那么我将确保所有2D直方图在余下的时间里都一样。