Matplotlib 从二维数据生成热图
我有一组X,Y数据点(来自遥感图像),通过教程我画了一个散点图,链接如下: 但当我试图绘制热图时,出现了一个错误:热图无法显示 有没有办法在热图中显示二维数据,热图中的不同颜色代表像素的密度 这是我的代码和结果:Matplotlib 从二维数据生成热图,matplotlib,image-processing,scipy,numpy-ndarray,rasterio,Matplotlib,Image Processing,Scipy,Numpy Ndarray,Rasterio,我有一组X,Y数据点(来自遥感图像),通过教程我画了一个散点图,链接如下: 但当我试图绘制热图时,出现了一个错误:热图无法显示 有没有办法在热图中显示二维数据,热图中的不同颜色代表像素的密度 这是我的代码和结果: import rasterio import numpy as np import matplotlib.pyplot as plt import matplotlib.cm as cm from scipy.ndimage.filters import gaussian_filter
import rasterio
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from scipy.ndimage.filters import gaussian_filter
def myplot(x, y, s, bins=1000):
heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
heatmap = gaussian_filter(heatmap, sigma=s)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
return heatmap.T, extent
fig, axs = plt.subplots(1, 2)
dataset = rasterio.open('E:/Jupyter Notebook/LC81490312016259LGN00/LC8_subset_layerstacking.tif')
red_band = dataset.read(4)
NIR_band = dataset.read(5)
np.seterr(divide='ignore', invalid='ignore')
ndvi = (NIR_band.astype(float)-red_band.astype(float))/(NIR_band.astype(float)+red_band.astype(float))
ndvi_flat = np.ndarray.flatten(ndvi)
red_band_flat = np.ndarray.flatten(red_band)
x = ndvi_flat
y = red_band_flat
sigmas = [0, 16]
for ax, s in zip(axs.flatten(), sigmas):
if s == 0:
ax.plot(x, y, 'k.', markersize=0.1)
#ax.set_aspect('equal')
ax.set_title("Scatter plot")
ax.set_xlabel('NDVI')
ax.set_ylabel('Red Reflectance')
else:
img, extent = myplot(x, y, s)
ax.imshow(img, origin='lower',cmap=cm.jet)
ax.set_title("Smoothing with $\sigma$ = %d" % s)
ax.set_xlabel('NDVI')
ax.set_ylabel('Red Reflectance')
plt.show()
左侧图像为黑色散点图(无像素密度信息),右侧图像为热图
我需要处理的代码和数据存储在GitHub中:您收到的确切错误消息是什么?我尝试使用随机输入数据来实现您的代码,它对我来说很好。另外,请注意彩虹颜色贴图是邪恶的:最好使用一个感知一致的颜色贴图,如viridis。@Solvalou没有错误消息,但无法正确显示热贴图。当时使用随机数据时,代码工作正常,但使用我需要处理的数据时,热图无法准确显示。我试着检查随机数据和我需要处理的数据之间的差异,但除了数据大小之外,我没有发现任何差异。好吧,现在我有点困惑你到底有什么问题。所以你附加的图像就是你得到的结果,对吗?左边的散点图看起来像你所期望的,但右边的热图却不是?首先,您没有在
imshow
中使用myplot
返回的extent
变量。否则,输出在我看来很好。可能只是数据有问题,因为似乎有一个非常密集的位置(图像中的红点)。你可以尝试使用对数刻度。只需从matplotlib导入LogNorm
via即可。colors导入LogNorm
并在imshow
中使用它(img,origin='lower',norm=LogNorm(vmin=np.min(img[img>0]),vmax=np.max(img))。这里,vmin
和vmax
是直方图的极值。@Solvalu非常感谢您提出的解决我的一些问题的建议。我故意删除了“extent”变量,因为只有这样才能显示右侧的图像。我可以将数据文件发送给您检查吗?因为很难清楚地描述这些问题。