繁体   English   中英

Python-2D直方图以对数比例绘制—错误:无法将float NaN转换为整数

[英]Python - 2D Histogram plot in log scale — Error: `cannot convert float NaN to integer`

这是我以前的图,我想转换为二维直方图。

在此处输入图片说明

mass_bh = (subhalos['SubhaloBHMass'] * 1e10 / 0.704) # in units of M_sol h^-1
vdisp = subhalos['SubhaloVelDisp']

nbins = 200
H, xedges, yedges = np.histogram2d(mass_bh,vdisp,bins=nbins)

fig2 = plt.figure()
plt.pcolormesh(xedges,yedges,Hmasked)
cbar = plt.colorbar()
cbar.ax.set_ylabel('g-r')

plt.ylabel(' $\log(\sigma)\quad$ [km s$^{-1}$] ')
plt.xlabel('$\log(M_{BH})\quad$ [M$_{\odot}$]')
plt.title('$M_{BH}-\sigma$ relation')

相反,这给了我

我以前的绘图将xy值都转换为对数比例。 但是对于这种直方图转换,效果不是很好。

在此处输入图片说明

我该如何解决?

谢谢!

@armatita认为问题在于数据是正确的。 我认为一切都取决于您如何在histogram2d进行装箱。 看看这个具有随机对数正态分布的示例是否有帮助。

import numpy as np
import matplotlib.pyplot as plt

n = 1000

x = np.logspace(2, 10, n)
y = x**1.5
y = y * np.random.lognormal(10, 3, n)

x_bins = np.logspace(np.log10(x.min()), np.log10(x.max()), np.sqrt(n))
y_bins = np.logspace(np.log10(y.min()), np.log10(y.max()), np.sqrt(n))
H, xedges, yedges = np.histogram2d(x, y, bins=[x_bins, y_bins])

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax1.plot(x, y, 'o')
ax1.set_xscale('log')
ax1.set_yscale('log')

ax2 = fig.add_subplot(212)
ax2.pcolormesh(xedges, yedges, H.T)
ax2.set_xscale('log')
ax2.set_yscale('log')

我得到以下图像,这是我相信您正在寻找的图像。 还要注意在H上的转置。 在此处输入图片说明

只是一个建议,可以激发您的好奇心。 尽管@lanery清楚地回答了这个问题,但我想分享另一种在python中获得漂亮的2d直方图的方法。 我不想使用np.histogram2d(通常会产生非常难看的直方图),而是要回收py-sphviewer ,这是一个使用自适应平滑内核渲染粒子模拟的python包。 考虑以下代码,该代码基于lanery的示例:

导入numpy作为np导入matplotlib.pyplot作为plt导入sphviewer作为sph

def myplot(x, y, extent=None, nb=8, xsize=500, ysize=500):   
    if(extent == None):
        xmin = np.min(x)
        xmax = np.max(x)
        ymin = np.min(y)
        ymax = np.max(y)
    else:
        xmin = extent[0]
        xmax = extent[1]
        ymin = extent[2]
        ymax = extent[3]

    k, = np.where( (x <= xmax) & (x >= xmin) & 
                   (y <= ymax) & (y >= ymin) )

    pos = np.zeros([3, len(k)])
    pos[0,:] = (x[k]-xmin)/(xmax-xmin)
    pos[1,:] = (y[k]-ymin)/(ymax-ymin)
    w = np.ones(len(k))

    P = sph.Particles(pos, w, nb=nb)
    S = sph.Scene(P)
    S.update_camera(r='infinity', x=0.5, y=0.5, z=0, 
                    extent=[-0.5,0.5,-0.5,0.5],
                    xsize=xsize, ysize=ysize)
    R = sph.Render(S)
    R.set_logscale()
    img = R.get_image()

    return img, [xmin,xmax,ymin,ymax]    


n = 1000

x = np.logspace(2, 10, n)
y = x**1.5
y = y * np.random.lognormal(10, 3, n)

H, xedges, yedges = np.histogram2d(x, y, bins=[np.logspace(np.log10(x.min()), np.log10(x.max())),
                                               np.logspace(np.log10(y.min()), np.log10(y.max()))])


img, extent = myplot(np.log10(x), np.log10(y))   #Call the function to make the 2d-histogram

fig = plt.figure()
ax1 = fig.add_subplot(311)
ax1.plot(x, y, 'o')
ax1.set_xscale('log')
ax1.set_yscale('log')

ax2 = fig.add_subplot(312)
ax2.pcolormesh(xedges, yedges, H.T)
ax2.set_xscale('log')
ax2.set_yscale('log')

ax3 = fig.add_subplot(313)
ax3.imshow(img, origin='lower', extent=extent, aspect='auto')

plt.show()

产生以下输出:

在此处输入图片说明

函数myplot()只是我编写的一个非常简单的函数,用于规范化数据并将其作为py-sphviewer的输入。 平滑内核的长度通常由参数nb给出,该参数指定要在其上进行平滑的邻居数。 尽管乍看之下似乎很复杂,但是其思想和实现非常简单,与np.histogram2d相比,结果要好得多。 但是,当然,这取决于您是否能够分发数据,以及这样做对研究的意义和后果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM