<p>在研究了<code>matplotlib</code>的<code>tripcolor</code>和<code>Colormap</code>代码之后,我想出了以下解决方案,这个解决方案似乎只有在使用“gouraud”着色时才有效(否则,它在推断脸部颜色方面做得很差;见下文)。</p>
<p>诀窍是创建一个颜色映射,当给定<code>n</code>且<code>0</code>和<code>1</code>(包括这两个值)之间的<code>n</code>会重新生成原始的颜色数组:</p>
<pre><code>def colors_to_cmap(colors):
'''
colors_to_cmap(nx3_or_nx4_rgba_array) yields a matplotlib colormap object that, when
that will reproduce the colors in the given array when passed a list of n evenly
spaced numbers between 0 and 1 (inclusive), where n is the length of the argument.
Example:
cmap = colors_to_cmap(colors)
zs = np.asarray(range(len(colors)), dtype=np.float) / (len(colors)-1)
# cmap(zs) should reproduce colors; cmap[zs[i]] == colors[i]
'''
colors = np.asarray(colors)
if colors.shape[1] == 3:
colors = np.hstack((colors, np.ones((len(colors),1))))
steps = (0.5 + np.asarray(range(len(colors)-1), dtype=np.float))/(len(colors) - 1)
return matplotlib.colors.LinearSegmentedColormap(
'auto_cmap',
{clrname: ([(0, col[0], col[0])] +
[(step, c0, c1) for (step,c0,c1) in zip(steps, col[:-1], col[1:])] +
[(1, col[-1], col[-1])])
for (clridx,clrname) in enumerate(['red', 'green', 'blue', 'alpha'])
for col in [colors[:,clridx]]},
N=len(colors))
</code></pre>
<p>同样,请注意,<code>'gouraud'</code>底纹是这项工作所必需的。为了说明失败的原因,下面的代码块显示了我的特定用例。(我正在绘制一部分带有部分透明数据覆盖的扁平皮层薄片)。在这段代码中,有40886个顶点(在<code>the_map.coordinates</code>)和81126个三角形(在<code>the_map.indexed_faces</code>)中;<code>colors</code>数组的形状是<code>(40886, 3)</code>。</p>
<p>以下代码适用于“gouraud”底纹:</p>
^{pr2}$
<blockquote>
<p><a href="https://i.stack.imgur.com/ZPvU7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ZPvU7.png" alt="Plot using Gouraud shading"/></a></p>
</blockquote>
<p>但是,如果没有“gouraud”明暗处理,面部颜色可能是根据顶点的平均值分配的(尚未验证这一点),这显然是错误的:</p>
<pre><code>plt.figure(figsize=(16,16))
plt.tripcolor(tri, zs, cmap=cmap)
</code></pre>
<blockquote>
<p><a href="https://i.stack.imgur.com/koj2a.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/koj2a.png" alt="enter image description here"/></a></p>
</blockquote>