matplotlib 如何为数组中的类别指定特定颜色

fafcakar  于 2023-05-23  发布在  其他
关注(0)|答案(1)|浏览(188)

我想展示一个地区的土地利用等级。
我有不同的光栅文件,其中包含土地使用的信息。像素的每个值对应于特定的土地利用类别。我想为每个类指定一种颜色,如下所示。这就是我正在做的:

from matplotlib.colors import ListedColormap
import rasterio
import numpy
import earthpy.plot as ep

cmap_values = [0, 11, 22, 33, 40, 55, 66, 77]
cmap_colors = ['white', ## 0: No Data
               'black', ## 11: urban 
               'darkorange', ## 22: Cropland
               'brown', ## 33: Pasture
               'darkgreen', ## 40: Forest
               'purple', ## 55: Grass
               'gray', ## 66: Other land
               'blue'  ## 77: water
              ] 
cmap = ListedColormap(cmap_colors)
value_text = ['No Data', 'Urban', 'Cropland', 'Pasture', 
             'Forest', 'Grass/shrubland', 
             'Other land', 'Water']

在某些情况下,我没有光栅中的所有类。例如,在下面的示例中,我只有

src = rasterio.open('myFile.tif')
data = src.read(1)
print(np.unique(data))
array([11, 22, 33, 40, 55, 77], dtype=uint8)

如果我尝试显示图像,它似乎没有为colorbar分配正确的值,而是从第一个值开始分配颜色。在下图中,颜色white表示urban类,black表示croplanddarkorange表示pasture,依此类推。我怎样才能保持相同的颜色类,为每一个案件,我遇到的。

f,ax=plt.subplots()
im = ax.imshow(data, cmap=cmap)
ep.draw_legend(im, titles=value_text, classes=cmap_values)

o3imoua4

o3imoua41#

您可以通过将值Map到索引来更改实际数据。
创建Map:

func = np.vectorize(lambda x: cmap_values.index(x))

得到data后,使用Map转换它:

data = func(data)

在imshow中,添加vmin和vmax,对应于颜色的最小和最大索引(避免需要自己的归一化规则):

ax.imshow(data, cmap=cmap, vmin = 0, vmax = len(cmap_colours)-1)

请注意,我假设没有边缘/奇怪的情况,例如您的数据具有cmap_values中列出的值之外的值。不过,如果存在这样的情况,一个比所使用的lambda函数更复杂的函数可能能够完成这项工作。

相关问题