我需要做一个二维密度图。但是,我自己计算“密度”。因此,基本上我有一个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
以我想要的方式放置刻度标签?
答案 0 :(得分:1)
我不确定我是否正确理解您。我了解的是,您想要获取数据的二维直方图,并希望使用一种颜色显示每个仓的计数/密度,同时保留仓边的真实坐标。
实际上,您可以结合使用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
显示的输出具有(nx, ny)
形状:值沿x轴对应的行。 答案 1 :(得分:0)
作为@TomdeGeus答案的补充,这可能会有所帮助。由于我需要绘制一个图,其中y轴的范围从0.5扩展到3.5,而x轴的范围从0扩展到40,因此它在图像中的压缩程度非常高,因此我可能不得不强制使用宽高比,工作。它显示的刻度线也有问题。
但是,在确定宽高比之后,我绝对建议您遵循Tom de Geus的回答,这是正确的方法。
因此,我仍将图像绘制在“像素”坐标上,即选择范围以使x轴和y轴计算像素,但从0开始,而不是像默认{{1}那样从-0.5开始}
plt.imshow()
fig, ax = plt.subplots()
im = ax.matshow(value_grid, origin='lower', extent=(0, len(x_edges)-1, 0, len(y_edges)-1)
在y轴上计算我想要的像素数(len(y_edges) - 1
是一个列表,其中包含我想像以前一样在y轴上显示的bin边界值。
然后我手动替换刻度线标签,但是我还需要正确地将其映射到正确的刻度线。
y_edges
这保留了ax.set_xticks(list(range(len(x_edges))))
ax.set_xticklabels(x_edges)
ax.set_yticks(list(range(len(y_edges))))
ax.set_yticklabels(y_edges)
产生的像素的平方性质,但是您要记住,仍然以像素为单位定义了基础轴(即,如果我想在坐标上放置一个点, 25.0,2.0),它看起来实际上并不会像下面那样位于该位置。