2015-02-17 73 views
3

我试图为matplotlib PolyCollection创建一个自定义颜色栏。一切似乎没问题,直到我试图绘制一个masked array。即使情节出现,颜色条也不再显示正确的颜色。绘制蒙面数组有没有不同的过程?绘制蒙版numpy阵列导致不正确的colorbar

我正在使用matplotlib 1.4.0和numpy 1.8。

这里是我的绘制代码:

import numpy 
import matplotlib as mpl 
import matplotlib.pyplot as plt 
from matplotlib.collections import PolyCollection 

vertices = numpy.load('vertices.npy') 
array = numpy.load('array.npy') 

# Take 2d slice out of 3D array 
slice_ = array[:, :, 0:1].flatten(order='F') 

fig, ax = plt.subplots() 

poly = PolyCollection(vertices, array=slice_, edgecolors='black', linewidth=.25) 

cm = mpl.colors.ListedColormap([(1.0, 0.0, 0.0), (.2, .5, .2)]) 
poly.set_cmap(cm) 

bounds = [.1, .4, .6] 
norm = mpl.colors.BoundaryNorm(bounds, cm.N) 

fig.colorbar(poly, ax=ax, orientation='vertical', boundaries=bounds, norm=norm) 
ax.add_collection(poly, autolim=True) 
ax.autoscale_view() 
plt.show() 

这里的情节是什么样子:

Plot without masked array

然而,当我切片之前绘制一个蒙面阵列具有以下变化

array = numpy.ma.array(array, mask=array > .5) 

我得到一个现在只显示一种颜色的颜色条。即使两种颜色都(正确)仍然显示在图中。

Plot with masked array

有一些技巧,密谋蒙面阵列时保持一致colobar?我知道我可以使用cm.set_bad来改变蒙面值的颜色,但这并不是我正在寻找的。我希望颜色条在这两个图之间显示相同,因为颜色和颜色条本身都应该保持不变。

回答

1

将BoundaryNorm传递给PolyCollection,poly。否则,poly.norm被默认设置为matplotlib.colors.Normalize实例:

In [119]: poly.norm 
Out[119]: <matplotlib.colors.Normalize at 0x7faac4dc8210> 

我没有经历过的源代码阶梯充分解释究竟是什么在你发布的代码发生的事情,但我推测这Normalize实例的相互作用和BoundaryNorm使得fig.colorbar看到的值的范围与您的预期不同。

在任何情况下,如果你通过norm=normPolyCollection,那么结果看起来是正确的:

import numpy 
import matplotlib as mpl 
import matplotlib.pyplot as plt 
import matplotlib.collections as mcoll 
import matplotlib.colors as mcolors 

numpy.random.seed(4) 
N, M = 3, 3 
vertices = numpy.random.random((N, M, 2)) 
array = numpy.random.random((1, N, 2)) 
# vertices = numpy.load('vertices.npy') 
# array = numpy.load('array.npy') 
array = numpy.ma.array(array, mask=array > .5) 
# Take 2d slice out of 3D array 
slice_ = array[:, :, 0:1].flatten(order='F') 
fig, ax = plt.subplots() 

bounds = [.1, .4, .6] 
cm = mpl.colors.ListedColormap([(1.0, 0.0, 0.0), (.2, .5, .2)]) 
norm = mpl.colors.BoundaryNorm(bounds, cm.N) 

poly = mcoll.PolyCollection(
    vertices, 
    array=slice_, 
    edgecolors='black', linewidth=.25, norm=norm) 

poly.set_cmap(cm) 

fig.colorbar(poly, ax=ax, orientation='vertical') 
ax.add_collection(poly, autolim=True) 
ax.autoscale_view() 
plt.show() 

enter image description here

+0

感谢您的建议!你说得对,'fig.colorbar'没有正确拉动'BoundaryNorm'实例。 – 2015-02-17 23:13:11