(问题的旧版本低于)
我正在定义以下自定义色彩映射,我将白色(#ffffff
)分配给浮点zero_pt
。
import matplotlib.colors as col
from matplotlib.colors import LinearSegmentedColormap
zero_pt = 0.98181818181818181
cmap = LinearSegmentedColormap.from_list(
'mycmap', [(0, 'blue'), (zero_pt, 'white'), (1, 'red')])
但是当我尝试从相同的zero_pt
值中检索十六进制颜色代码时,我没有像我期望的那样得到#ffffff
(即:white):
rgb = cmap(zero_pt)[:3]
print(col.rgb2hex(rgb))
> u'#ffdcdc'
为什么会这样,我该如何解决这个问题?
这里的老问题
我需要定义一个自定义色图,其中负值以蓝色显示,零值以白色显示,正值以红色显示。代码如下,以及必要的数据文件(data.pkl)和此处(edges.pkl)。
import pickle
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
with open('data.pkl', 'r') as f:
H = pickle.load(f)
with open('edges.pkl', 'r') as f:
edges = pickle.load(f)
# Define zero point for empty bins which should be colored in white.
zero_pt = 1. - H.max() / (H.max() - H.min())
print(H.min(), H.max(), zero_pt)
cmap = LinearSegmentedColormap.from_list(
'mycmap', [(0, 'blue'), (zero_pt, 'white'), (1, 'red')])
Y, X = np.meshgrid(edges[0], edges[1])
plt.pcolormesh(X, Y, H, cmap=cmap, vmin=H.min(), vmax=H.max())
plt.show()
这导致
如果我们检查H
数组,我们会发现有很多零值,应该以白色显示,而在上图中显示为粉红色。
这不会发生我使用的所有数据,它只是偶尔发生。我认为问题与舍入有关?有没有办法强制像这样的情况以白色显示零值?
答案 0 :(得分:1)
正如评论中所说,如果1/N
是色彩映射中的颜色数,则需要将零点值舍入为N
的倍数。当然,色点图中零点值与任何其他颜色之间的差异必须大于1/N
。
所以这是一个解决方案
import matplotlib.colors as col
from matplotlib.colors import LinearSegmentedColormap
import numpy as np
N=256
zero_pt0 = 0.98181818181818181
zero_pt_rounded = np.ceil(zero_pt0*(N-1))/float(N-1)
print (zero_pt_rounded)
cmap = LinearSegmentedColormap.from_list(
'mycmap', [(0, 'blue'), (zero_pt_rounded, 'white'), (1, 'red')], N=N)
# verify if original point zero_pt0 gives white color
rgb = cmap(zero_pt0)[:3]
print(col.rgb2hex(rgb))
关于您的旧问题:目前尚不清楚zero_pt = 1. - H.max() / (H.max() - H.min())
行应该做什么。
我猜你需要把
data_value_for_white color = ...
zero_pt = (data_value_for_white color - H.min()) / (H.max() - H.min())
此外,为了确保色彩图中的白色覆盖所需的值,我们需要使色彩图中的两个相邻颜色变为白色。
N = 256 # number of colors in the colormap
zero_pt0 = np.floor(zero_pt*(N-1))/float(N-1)
zero_pt1 = np.ceil(zero_pt*(N-1))/float(N-1)
cmap = LinearSegmentedColormap.from_list('mycmap',
[(0, 'blue'), (zero_pt0, 'white'),(zero_pt1, 'white'), (1, 'red')], N=N)
因此,完整的解决方案如下:
import pickle
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, rgb2hex
with open('data.pkl', 'r') as f:
H = pickle.load(f)
with open('edges.pkl', 'r') as f:
edges = pickle.load(f)
# Define zero point for empty bins which should be colored in white.
data_value_for_white_color = 0.
zero_pt = (data_value_for_white_color - H.min()) / float(H.max() - H.min())
N=256
zero_pt0 = np.floor(zero_pt*(N-1))/float(N-1)
zero_pt1 = np.ceil(zero_pt*(N-1))/float(N-1)
cmap = LinearSegmentedColormap.from_list('mycmap',
[(0, 'blue'), (zero_pt0, 'white'),(zero_pt1, 'white'), (1, 'red')], N=N)
Y, X = np.meshgrid(edges[0], edges[1])
plt.pcolormesh(X, Y, H, cmap=cmap, vmin=H.min(), vmax=H.max())
plt.show()