我正在尝试在Python中绘制热图。
我已经研究了几个教程,但仍然无法实现我所需要的。
我的数据有3列:X,Y(散点图中的坐标)和群集(每行放置一个组/群集)。所需的输出应该看起来像这样(6个类和X,Y点分布在彩色区域中):

python - 在Python中制作x,y,z数据的热图-LMLPHP

我当前的代码:

# libraries
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import kde
from scipy.interpolate import griddata

# Get the data (csv file is hosted on the web)
url = 'https://raw.githubusercontent.com/ampil/sandbox/master/latest-sales-sample.csv'
df = pd.read_csv(url, sep = ';')
df = df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
# create data
x = df['X']
y = np.log(df['Y'])
z = df['cluster']

# target grid to interpolate to
xi = yi = np.arange(0, 1.01, 0.01)
xi, yi = np.meshgrid(xi,yi)

# interpolate
zi = griddata((x,y),z,(xi,yi),method='cubic')

# plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis((x.min(), x.max(), y.min(), y.max()))
plt.contourf(xi, yi, zi, np.arange(0, 1.01, 0.01), cmap='coolwarm')
plt.plot(x,y,'k.')
plt.xlabel('x',fontsize=16)
plt.ylabel('y',fontsize=16)
plt.show()
plt.close(fig)


给我

python - 在Python中制作x,y,z数据的热图-LMLPHP

稍后,我计划通过破折号发布图表。

任何帮助表示赞赏!

最佳答案

我的答案是对warped提供的答案的小修改。

区别在于在contourf方法调用中包含了参数“ extend”。

https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.contourf.html

有关最小/最大颜色图行为的更多信息,请参见:

https://matplotlib.org/3.1.1/gallery/images_contours_and_fields/contourf_demo.html#sphx-glr-gallery-images-contours-and-fields-contourf-demo-py

# libraries
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import kde
from scipy.interpolate import griddata

# Get the data (csv file is hosted on the web)
url = 'https://raw.githubusercontent.com/ampil/sandbox/master/latest-sales-sample.csv'
df = pd.read_csv(url, sep = ';')
df = df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
# create data
x = df['X']
y = np.log(df['Y'])
z = df['cluster']

#following 2 lines provided by user-warped
xi = np.arange(0, np.max(x), 0.1)
yi = np.arange(0, np.max(y), 0.1)

xi, yi = np.meshgrid(xi,yi)

# interpolate
zi = griddata((x,y),z,(xi,yi),method='cubic')

#define color map...which you can choose to modify with 'set_under' and 'set_over'
#as per: https://matplotlib.org/3.1.1/gallery/images_contours_and_fields/contourf_demo.html#sphx-glr-gallery-images-contours-and-fields-contourf-demo-py
cmap = plt.cm.get_cmap("coolwarm")

fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis((x.min(), x.max(), y.min(), y.max()))

#added the 'extend' parameter to user:warped edit as per documentation of plt.contourf
#https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.contourf.html
plt.contourf(xi, yi, zi, levels=[1,2,3,4,5,6], cmap=cmap, extend='both')
plt.plot(x, y,'k.')

plt.xlabel('x',fontsize=16)
plt.ylabel('y',fontsize=16)
plt.show()


python - 在Python中制作x,y,z数据的热图-LMLPHP

至于将颜色扩展到现在以外的颜色……您会得到与主要区域看起来非常不同的结果,并且可能没有什么意义。如果这是GIS应用程序,那么我将这些外部像素设置为“ NODATA”。

编辑:
提供证据表明填充外部看起来很奇怪...

使用固定的gdal方法填充nodata,结果如下所示:

python - 在Python中制作x,y,z数据的热图-LMLPHP

这既快速又肮脏,可能存在其他方法,但看起来可能同样奇怪。如果您没有gdal,也许numpy.nan_to_num是另一个解决方案。

如果您感到好奇...这是代码(从上一个代码块继续):

import gdal
ds = gdal.GetDriverByName('MEM').Create('', zi.shape[1], zi.shape[0], 1, gdal.GDT_Float32)
in_band = ds.GetRasterBand(1)
in_band.SetNoDataValue(-9999)
in_band.FlushCache()

raster_data = np.copy(zi)
raster_data[np.isnan(zi)] = -9999

in_band.WriteArray(raster_data)

#this line takes a while to run...grab a coffee
result = gdal.FillNodata(in_band, None, maxSearchDist=20000, smoothingIterations=0)
in_band.FlushCache()

newz = in_band.ReadAsArray()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis((x.min(), x.max(), y.min(), y.max()))

#added the 'extend' parameter as per documentation of plt.contourf
#https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.contourf.html
plt.contourf(xi, yi, newz, levels=[1,2,3,4,5,6], cmap=cmap, extend='both')
plt.plot(x, y,'k.')

plt.xlabel('x',fontsize=16)
plt.ylabel('y',fontsize=16)
plt.show()

10-08 02:32