s.k*_*s.k 5 python arrays numpy matplotlib imshow
我有一个 2D NumPy数组,其中包含二进制值(0 和 1)+1 个附加值(-999),表示“无数据”。
这是一个虚拟示例:
import numpy as np
arr = np.random.randint(2, size=(100,))
# this no-data value has to be large compared to the data range:
arr[np.random.randint(1, 100, 20)] = -999
arr = arr.astype(np.float32)
arr.reshape((10,10))
>> arr
array([[ 1, 1, 0, 1, 0, 0, -999, 1, 0, 0],
[ 0, 1, 0, 0, 1, 0, 1, 1, 1, 1],
[ 1, 1, 1, 1, -999, 0, 1, -999, 1, -999],
[ 0, 1, -999, 1, 0, 1, 1, 1, 0, 1],
[-999, -999, 1, 1, 1, 0, 0, 0, 0, 1],
[-999, 1, 1, -999, 0, 1, 1, -999, -999, 1],
[ 1, 1, 1, 0, 0, 1, 1, -999, -999, 0],
[-999, 0, 1, 0, -999, -999, 1, 1, 1, 1],
[ 1, 1, 0, 1, 1, 0, 0, 0, 1, 0],
[ 1, -999, -999, 0, 1, 0, 1, 0, 1, 1]],
dtype=float32)
Run Code Online (Sandbox Code Playgroud)
当我使用 绘制此数组时matplotlib.imshow(),由于 0 和 1 像素与整个数据范围相比非常接近,因此它们具有几乎相同的颜色,这使得它们完全无法区分:
import matplotlib.pyplot as plt
plt.imshow(arr)
Run Code Online (Sandbox Code Playgroud)
黄色表示值为 0 和 1 的像素,深紫色表示 -999 个像素。
我想将这些像素值映射到以下值:
color_list = {-999: np.array([189, 184, 181]), # gray tone
0: np.array([0, 255, 0]), # green
1: np.array([255, 180, 180])} # light red
Run Code Online (Sandbox Code Playgroud)
这似乎有效:
data_3d = np.ndarray(shape=(arr.shape[0], arr.shape[1], 3), dtype=int)
for i in range(0, arr.shape[0]):
for j in range(0, arr.shape[1]):
data_3d[i][j] = color_map[arr[i][j]]
plt.imshow(data_3d)
Run Code Online (Sandbox Code Playgroud)
屏蔽版本也可以工作:
# Normalizing the color_dict is mandatory to avoid a ValueError:
# "RGBA values should be within 0-1 range"
color_dict = {-999: np.array([189, 184, 181])/.255, # gray tone
0: np.array([0, 255, 0])/.255, # green
1: np.array([255, 180, 180])/.255} # light red
mask = np.ma.masked_where(arr == -999, arr)
# Here the indices in square brackets are the actual values of the pixels
# which serves as keys in the color_dict:
# see https://stackoverflow.com/questions/26610389/defining-a-binary-matplotlib-colormap
customcm = mpl.colors.ListedColormap( [ color_list[0], color_list[1] ] )
customcm.set_bad( color_list[-999] )
plt.imshow(mask, cmap=customcm)
Run Code Online (Sandbox Code Playgroud)
但我想知道是否可以完全避免双for循环和/或在这里创建新数组(包括掩码)?
例如,动态地,仅使用 matplotlib,因为我的一些数组非常大(高达 ~2GB),并且我希望通过避免构建另一个相同大小的数组(最多 3 个)来尽可能降低内存消耗频道...
版本控制:
>>> numpy.__version__
'1.19.5'
>>> mpl.__version__
'3.3.4'
Run Code Online (Sandbox Code Playgroud)
ListedColormap这是使用和 的示例np.nan。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
arr = np.array(
[
[1, 1, 0, 1, 0, 0, -999, 1, 0, 0],
[0, 1, 0, 0, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 1, -999, 0, 1, -999, 1, -999],
[0, 1, -999, 1, 0, 1, 1, 1, 0, 1],
[-999, -999, 1, 1, 1, 0, 0, 0, 0, 1],
[-999, 1, 1, -999, 0, 1, 1, -999, -999, 1],
[1, 1, 1, 0, 0, 1, 1, -999, -999, 0],
[-999, 0, 1, 0, -999, -999, 1, 1, 1, 1],
[1, 1, 0, 1, 1, 0, 0, 0, 1, 0],
[1, -999, -999, 0, 1, 0, 1, 0, 1, 1],
],
dtype="float",
)
arr[arr < 0] = np.nan
cmap = ListedColormap(["green", "orangered"])
cmap.set_bad("silver")
plt.imshow(arr, cmap=cmap)
Run Code Online (Sandbox Code Playgroud)
其产生:
| 归档时间: |
|
| 查看次数: |
3259 次 |
| 最近记录: |