微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无插值的不规则间隔数据的热图

如何解决无插值的不规则间隔数据的热图

我想绘制一个热图,其中输入数据不在典型的矩形间隔网格中。以下是一些示例数据:

import numpy as np
xmin = 6
xmax= 12
ymin = 0

x = np.linspace(xmin,xmax,100)
ymax = x**2
final = []

for i in range(len(ymax)):

    yrange = np.linspace(0,ymax[i],100)

    for j in range(len(yrange)):
        intensity = np.random.rand()
        final.append([x[i],yrange[j],intensity])
    
    
    
data_for_plotting = np.asarray(final) # (10000,3) shaped array

我想将强度(在颜色条中)绘制为表示位置的 (x,y) 的函数,我想在没有插值的情况下执行此操作。

这是我使用 matplotlib 的网格数据和线性插值的解决方案。

import matplotlib.pyplot as plt
from matplotlib.mlab import griddata

total_length = 100
x1 = np.linspace(min(data_for_plotting[:,0]),max(data_for_plotting[:,total_length)
y1 = np.linspace(min(data_for_plotting[:,1]),total_length)
z1 = griddata(data_for_plotting[:,0],data_for_plotting[:,1],2],x1,y1,interp='linear')
p=plt.pcolormesh(x1,z1,vmin = 0.,vmax=1.0,cmap='viridis')
clb = plt.colorbar(p)
plt.show()

我正在寻找一种没有插值的替代解决方案,因为我想在我的 x 和 y 位置(像素大小/矩形)中看到最小的测量单位。根据上面给出的示例数据,我预计像素的高度会随着 x 的值增大而增加

解决方法

我不确定 matplotlib.mlab.griddata 是关于什么的。也许是一些非常旧的版本?

您可以使用 scipy.interpolate.griddata,它需要其参数格式略有不同。 method='nearest' 关闭插值(默认 method='linear')。

以下是您的测试数据的外观(有关更多解释和示例,请参阅 griddata 的文档):

import matplotlib.pyplot as plt
from scipy.interpolate import griddata
import numpy as np

xmin = 6
xmax = 12
ymin = 0
x = np.linspace(xmin,xmax,100)
ymax = x ** 2
final = []
for i in range(len(ymax)):
    yrange = np.linspace(0,ymax[i],100)
    for j in range(len(yrange)):
        intensity = np.random.rand()
        final.append([x[i],yrange[j],intensity])
data_for_plotting = np.asarray(final)  # (10000,3) shaped array

total_length = 100
x1 = np.linspace(min(data_for_plotting[:,0]),max(data_for_plotting[:,total_length)
y1 = np.linspace(min(data_for_plotting[:,1]),total_length)
grid_x,grid_y = np.meshgrid(x1,y1)
z1 = griddata(data_for_plotting[:,:2],data_for_plotting[:,2],(grid_x,grid_y),method='nearest')
img = plt.imshow(z1,extent=[x1[0],x1[-1],y1[0],y1[-1]],origin='lower',vmin=0,vmax=1,cmap='inferno',aspect='auto')
cbar = plt.colorbar(img)
plt.show()

griddata with imshow

另一种方法是为每个延长的像素创建一个矩形。请注意,这可能是一个相当慢的操作。如果确实需要,可以为每一列创建一个 pcolormesh

import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
import numpy as np

# ... create x and data_for_plotting as before 

fig,ax = plt.subplots()
cmap = plt.get_cmap('inferno')
norm = plt.Normalize(0,1)
x_step = x[1] - x[0]
y_step = 0
for i,(xi,yi,intensity_i) in enumerate(data_for_plotting):
    if i + 1 < len(data_for_plotting) and data_for_plotting[i + 1,0] == xi:  # when False,the last y_step is reused
        y_step = data_for_plotting[i + 1,1] - yi
    ax.add_artist(plt.Rectangle((xi,yi),x_step,y_step,color=cmap(norm(intensity_i))))
cbar = plt.colorbar(ScalarMappable(cmap=cmap,norm=norm))
ax.set_xlim(x[0],x[-1])
ax.set_ylim(0,1].max())
plt.tight_layout()
plt.show()

colormesh with unequal rectangles

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。