简体   繁体   English

使用Matplotlib.image的自定义颜色图

[英]Custom Colormap using Matplotlib.image

I am using matplotlib.image.imsave('file.png',file,cmap=cmap) to save a .png of a 2d Numpy array where the array can only have values of 0, 1 or 10. I would like 0 to be white, 1 to be green and 10 to be red. 我正在使用matplotlib.image.imsave('file.png',file,cmap=cmap)保存2d Numpy数组的.png ,其中该数组只能具有0、1或10的值。我希望0到是白色,1是绿色,10是红色。 I saw something similar at this question: Matplotlib: Custom colormap with three colors . 我在这个问题上看到了类似的东西: Matplotlib:具有三种颜色的自定义颜色图 The problem is that imsave does not take norm as an argument but using pyplot is too slow for my application. 问题是imsave不会将norm作为参数,但是对我的应用程序而言,使用pyplot太慢了。 Any assistance would be appreciated! 任何援助将不胜感激!

The input array consisting of values [0,1,10] is not really an image array. 由值[0,1,10]组成的输入数组实际上不是图像数组。 Image arrays would go from 0 to 255 or from 0. to 1. . 图像数组将从0255或从0.1.

a. 一种。 using a LinearSegmentedColormap 使用LinearSegmentedColormap

An idea can be to normalize your array im to 1.: im = im/im.max() . 一个想法是将数组im标准化为1 .: im = im/im.max() It is then possible to create a colormap with the values 0 -> white, 0.1 -> green, 1 -> red using matplotlib.colors.LinearSegmentedColormap.from_list . 然后可以使用matplotlib.colors.LinearSegmentedColormap.from_list创建值为0 -> white, 0.1 -> green, 1 -> red

import matplotlib.image
import numpy as np

im = np.random.choice([0,1,10], size=(90, 90), p=[0.5,0.3,0.2])

im2 = im/10.
clist = [(0,"white"), (1./10.,"green"), (1, "red")]
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("name", clist)
matplotlib.image.imsave(__file__+'.png', im, cmap=cmap)

在此处输入图片说明

The corresponding pyplot plot 对应的pyplot图

import matplotlib.pyplot as plt
plt.imshow(im, cmap=cmap)
plt.colorbar(ticks=[0,1,10])
plt.show()

would look like this 看起来像这样

在此处输入图片说明

b. using a ListedColormap 使用ListedColormap

A ListedColormap can be used to generate a colormap of the three colors white, green and red. ListedColormap可用于生成白色,绿色和红色这三种颜色的颜色图。 In this colormap the colors are equally spaced, so one needs to map the image array to equally spaced values as well. 在此颜色图中,颜色是等距分布的,因此也需要将图像数组映射到等距的值。 This can be done using np.unique(im,return_inverse=True)[1].reshape(im.shape) , which returns an array containing only the values [0,1,2] . 可以使用np.unique(im,return_inverse=True)[1].reshape(im.shape) ,该返回仅包含值[0,1,2]的数组。 We again need to normalize to 1. 我们再次需要归一化为1。

im = np.random.choice([0,1,10], size=(90, 90), p=[0.5,0.3,0.2])

im2 = np.unique(im,return_inverse=True)[1].reshape(im.shape)
im3 = im2/float(im2.max())

clist = ["white", "green","red"]
cmap = matplotlib.colors.ListedColormap(clist)
matplotlib.image.imsave(__file__+'2.png',im3, cmap=cmap) 

在此处输入图片说明

While the output image looks exactly the same as above, the corresponding matplotlib plot would have a different colorbar. 虽然输出图像看起来与上面的图像完全相同,但是相应的matplotlib图将具有不同的颜色条。

import matplotlib.pyplot as plt
plt.imshow(im2, cmap=cmap)
cb = plt.colorbar(ticks=[0,1,2])
cb.ax.set_yticklabels([0,1,10])
plt.show()

在此处输入图片说明

Just build a (N, M, 3) array and treat it as image-pixels in RGB-mode. 只需构建一个(N, M, 3)数组并将其作为RGB模式下的图像像素即可。 Then it's enough to map your 3 unique values to those 3 colors. 然后,将您的3个唯一值映射到这3种颜色就足够了。

Code: 码:

import numpy as np
from scipy.misc import imsave

raw = np.random.choice((0,1,10), size=(500, 500))
img = np.empty((raw.shape[0], raw.shape[1], 3))

img[raw == 0] = (255, 255, 255)  # RGB -> white
img[raw == 1] = (0,255,0)        #        green
img[raw == 10] = (255,0,0)       #        red

imsave('image.png', img)

在此处输入图片说明

I'm using scipy's imsave here, but the matplotlib one probably works the same. 我在这里使用scipy的imsave ,但是matplotlib可能工作相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM