我需要做一个二维密度图。但是,我自己计算“密度”。因此,基本上我有一个NxM
值数组,只能使用plt.matshow
(或imshow)绘制。
fig, ax = plt.subplots()
im = ax.matshow(value_array)
ax.set_xticklabels(x_edges - 2.5)
ax.set_yticklabels(y_edges - 0.25)
但是,在这种情况下,轴值是图中的像素,而我确实希望它显示一些用户定义的值。因此,我如上所述手动更改了刻度标签。
这仍然存在问题。
matshow
仍然认为刻度标签正在标记图像中的“像素”,因此刻度标签打印在每个像素正方形的“中间”。但是,就像我说的那样,我真正想绘制的内容更像是密度图,因此每个“像素正方形”都表示x,y空间中的一个bin。将刻度线标签打印在正方形边缘上会更加有意义,就像通常对直方图和频率图所做的方式一样。我应该继续使用matshow还是这样做呢?例如,我可以使用
plt.hist2d
但手动设置“高度”而不输入大量样本数据吗?否则,我如何使plt.matshow
以我希望的方式放置刻度标签? 最佳答案
我不确定我是否正确理解您。我了解的是,您想要获取数据的二维直方图,并希望使用一种颜色显示每个仓的计数/密度,同时保留仓边的真实坐标。
实际上,您可以结合使用numpy.histogram2d
和matplotlib.pyplot.imshow
。
让我开始警告。使用imshow
可以显示像素。因此,您隐式地假设箱沿每个轴的大小均一。它们的宽度和高度可能不同,但是每个容器的宽度/高度必须相等,以使表示形式公平。
要实现我认为您想要的功能,您将必须使用以下代码:
import matplotlib.pyplot as plt
import numpy as np
N = 100000
x = np.random.randn(N)
y = np.random.weibull(2.,N)
P, xedges, yedges = np.histogram2d(x, y, bins=(np.linspace(-4,+5,10), np.linspace(0,4,21)), density=True)
fig, ax = plt.subplots()
cax = ax.imshow(P.T, extent=(xedges[0], xedges[-1], yedges[0], yedges[-1]),
origin='lower', interpolation='nearest', clim=(0,.4), cmap='afmhot_r')
cbar = fig.colorbar(cax,aspect=10)
ax.set_aspect('auto')
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.savefig('test.png')
plt.show()
哪个情节
棘手的部分是要获得自然的输出:
您必须覆盖
imshow
的默认设置,即将图像的原点放在图像顶部。如图所示,您可以使用origin='lower'
选项。您必须绘制
numpy.histogram
的转置输出,因为imshow
照原样显示矩阵,而numpy.histogram
show的输出具有形状(nx, ny)
:x轴上的值对应于行。您可能必须更改纵横比,请参见this answer。
关于python - 如何进行matshow或imshow,但将轴值显示为bin边界(即,如在2d频率/密度图上那样),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54863543/