英文:
How to assign specific color to a category in an array
问题
Sure, here's the translated code portion:
我想展示一个地区的土地利用分类。
我有不同的栅格文件,其中包含土地利用信息。每个像素的值对应于特定的土地利用类别。我想为每个类别分配如下所示的颜色。这是我正在做的事情:
从matplotlib.colors导入ListedColormap
import rasterio
import numpy
import earthpy.plot as ep
cmap_values = [0, 11, 22, 33, 40, 55, 66, 77]
cmap_colors = ['white', ## 0: 无数据
'black', ## 11: 城市
'darkorange', ## 22: 农田
'brown', ## 33: 牧场
'darkgreen', ## 40: 森林
'purple', ## 55: 草地
'gray', ## 66: 其他土地
'blue' ## 77: 水域
]
cmap = ListedColormap(cmap_colors)
value_text = ['无数据', '城市', '农田', '牧场',
'森林', '草地/灌丛地',
'其他土地', '水域']
在某些情况下,栅格中并不包含所有的类别。例如,在以下示例中,我只有
src = rasterio.open('myFile.tif')
data = src.read(1)
print(np.unique(data))
array([11, 22, 33, 40, 55, 77], dtype=uint8)
如果我尝试显示图像,似乎它没有为色标分配正确的值,而是从第一个值开始分配颜色。在下图中,颜色'white'表示'城市'类别,'black'表示'农田','darkorange'表示'牧场',依此类推。如何在遇到每种情况时保持相同的颜色-类别关联。
f,ax=plt.subplots()
im = ax.imshow(data, cmap=cmap)
ep.draw_legend(im, titles=value_text, classes=cmap_values)
If you have any specific questions or need further assistance with this code, please let me know.
英文:
I want to show the land use classes of a region.
I have different raster files that contain information of land use. Each value of the pixel correspond to a specific land use class. I want to assign to each class a color as shown below. This is what I am doing:
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']
In some cases I do not have all the classes in the raster. For instance in the following example I have only
src = rasterio.open('myFile.tif')
data = src.read(1)
print(np.unique(data))
array([11, 22, 33, 40, 55, 77], dtype=uint8)
If I try to show the image it seems that it does not assign the right values to the colorbar but is assigns the color starting from the first value. In the figure below the color white
is for the urban
class, the black
for the cropland
, the darkorange
for the pasture
and so on. How can I keep the same color-class for each case that I encounter.
f,ax=plt.subplots()
im = ax.imshow(data, cmap=cmap)
ep.draw_legend(im, titles=value_text, classes=cmap_values)
答案1
得分: 1
创建一个映射:
func = np.vectorize(lambda x: cmap_values.index(x))
一旦获取到你的 data
,使用这个映射进行转换:
data = func(data)
在 imshow 中,添加 vmin 和 vmax,分别对应你的颜色的最小和最大索引(避免需要自定义规范化规则):
ax.imshow(data, cmap=cmap, vmin=0, vmax=len(cmap_colours)-1)
请注意,我假设没有边界或奇怪的情况,比如你的数据值不在 cmap_values 中列出的情况。不过,如果存在这样的情况,可能需要一个比 lambda 函数更复杂的函数来完成这项任务。
英文:
You can change the actual data by mapping the values to the indices.
Create a mapping:
func = np.vectorize(lambda x: cmap_values.index(x))
Once you get your data
, convert it with the mapping:
data = func(data)
In the imshow, add vmin and vmax, corresponding to the min and max indices of your colours (avoiding the need for your own normalization rule):
ax.imshow(data, cmap=cmap, vmin = 0, vmax = len(cmap_colours)-1)
Note that I am assuming no edge/weird cases, such as your data having a value outside of the ones listed in cmap_values. Though, a more complex function than the lambda one used, may be able to do the job, if cases like that exist.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论