<p>首先,标记为“答案”的回答是错误的(见我上面的评论),但帮助我提出了另外两个解决方案。</p>
<p><strong>1。一个简单而直接的解决方案</strong></p>
<p>在提供自定义级别的同时使用extend命令:</p>
<pre><code>import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
plt.title('Simplest default with labels')
levels = np.linspace(0.0, 3.0, 7)
CS = plt.contourf(X, Y, Z, levels=levels, cmap=cm.coolwarm, extend='min')
colorbar = plt.colorbar(CS)
plt.show()
</code></pre>
<p><a href="https://i.stack.imgur.com/RxqHZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RxqHZ.png" alt="output method 1"/></a></p>
<p><strong>2。更复杂的解决方案</strong></p>
<p>是在上面的答案中提供的,尽管它需要适应特定的情况,一个人可以很容易地以一个色条结束,它的水平与实际绘图中的水平不同。我发现这很危险,所以我试图用一个可以在任何上下文中安全调用的函数来包装它:</p>
<pre><code>def clippedcolorbar(CS, **kwargs):
from matplotlib.cm import ScalarMappable
from numpy import arange, floor, ceil
fig = CS.ax.get_figure()
vmin = CS.get_clim()[0]
vmax = CS.get_clim()[1]
m = ScalarMappable(cmap=CS.get_cmap())
m.set_array(CS.get_array())
m.set_clim(CS.get_clim())
step = CS.levels[1] - CS.levels[0]
cliplower = CS.zmin<vmin
clipupper = CS.zmax>vmax
noextend = 'extend' in kwargs.keys() and kwargs['extend']=='neither'
# set the colorbar boundaries
boundaries = arange((floor(vmin/step)-1+1*(cliplower and noextend))*step, (ceil(vmax/step)+1-1*(clipupper and noextend))*step, step)
kwargs['boundaries'] = boundaries
# if the z-values are outside the colorbar range, add extend marker(s)
# This behavior can be disabled by providing extend='neither' to the function call
if not('extend' in kwargs.keys()) or kwargs['extend'] in ['min','max']:
extend_min = cliplower or ( 'extend' in kwargs.keys() and kwargs['extend']=='min' )
extend_max = clipupper or ( 'extend' in kwargs.keys() and kwargs['extend']=='max' )
if extend_min and extend_max:
kwargs['extend'] = 'both'
elif extend_min:
kwargs['extend'] = 'min'
elif extend_max:
kwargs['extend'] = 'max'
return fig.colorbar(m, **kwargs)
</code></pre>
<p>函数中的主要命令对应于千焦在他/她的答案中提出的建议,但是需要更多的行,以通过从<code>contourf</code>对象中提取所有信息来避免所有显式和潜在的错误赋值。</p>
<p>用法:</p>
<p>操作要求从0到3的级别。最深的蓝色表示0以下的值,因此我发现扩展标记很有用。</p>
<pre><code>import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
plt.figure()
plt.title('Simplest default with labels')
CS = plt.contourf(X, Y, Z, levels=6, vmin=0.0, vmax=3.0, cmap=cm.coolwarm)
def clippedcolorbar(CS, **kwargs):
from matplotlib.cm import ScalarMappable
from numpy import arange, floor, ceil
fig = CS.ax.get_figure()
vmin = CS.get_clim()[0]
vmax = CS.get_clim()[1]
m = ScalarMappable(cmap=CS.get_cmap())
m.set_array(CS.get_array())
m.set_clim(CS.get_clim())
step = CS.levels[1] - CS.levels[0]
cliplower = CS.zmin<vmin
clipupper = CS.zmax>vmax
noextend = 'extend' in kwargs.keys() and kwargs['extend']=='neither'
# set the colorbar boundaries
boundaries = arange((floor(vmin/step)-1+1*(cliplower and noextend))*step, (ceil(vmax/step)+1-1*(clipupper and noextend))*step, step)
# boundaries = [vmin]+CS.levels[ (CS.levels>vmin) & (CS.levels<vmax) ].tolist()+[vmax] # fails when vmin<CS.levels.min()
kwargs['boundaries'] = boundaries
# if the z-values are outside the colorbar range, add extend marker(s)
# This behavior can be disabled by providing extend='neither' to the function call
if not('extend' in kwargs.keys()) or kwargs['extend'] in ['min','max']:
extend_min = cliplower or ( 'extend' in kwargs.keys() and kwargs['extend']=='min' )
extend_max = clipupper or ( 'extend' in kwargs.keys() and kwargs['extend']=='max' )
if extend_min and extend_max:
kwargs['extend'] = 'both'
elif extend_min:
kwargs['extend'] = 'min'
elif extend_max:
kwargs['extend'] = 'max'
return fig.colorbar(m, **kwargs)
colorbar = clippedcolorbar(CS)
plt.show()
</code></pre>
<p><a href="https://i.stack.imgur.com/BAj5z.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/BAj5z.png" alt="output"/></a></p>
<p>可以通过调用<code>clippedcolorbar(CS, extend='neither')</code>而不是<code>clippedcolorbar(CS)</code>来禁用扩展标记。</p>
<p><a href="https://i.stack.imgur.com/oLcGw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oLcGw.png" alt="output with extend='neither'"/></a></p>