为每个顶点使用RGB值的tripcolor

2024-09-30 10:27:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个2D三角形网格,它存储在一个变量tri(amatplotlib.tri.三角剖分对象);我可以很容易地用matplotlib的tripcolor函数绘制网格,一切正常。但是,对于每个顶点我也有(r,g,b)三元组(vcolors),而且这些值不是沿着一个单一的维度下降的,因此不容易转换成彩色地图(例如,想象一下,如果你在公园的一张大照片上覆盖了一个三角形网格,然后为每个顶点分配了它下面像素的颜色)。在

我想我可以这样做:

matplotlib.pyplot.tripcolor(tri, vcolors)

ValueError: Collections can only map rank 1 arrays

有没有一种方便的方法可以把vcolors样的(nx3)矩阵转换成tripcolor可以使用的东西吗?有没有tripcolor的替代品可以接受顶点颜色?在

我尝试过的一件事是制作我自己的颜色图:

^{pr2}$

但是,这个函数什么也没做——没有出现图形,也没有出现错误;函数返回一个图形句柄,但是没有任何内容被呈现(我使用的是IPython笔记本)。请注意,如果我调用以下选项,则图显示得很好:

tripcolor(tri, np.zeros(len(vcolors)))
matplotlib.pyplot.show()

我使用的是python2.7。在


Tags: 对象函数图形网格matplotlib颜色tri剖分
3条回答

在研究了matplotlibtripcolorColormap代码之后,我想出了以下解决方案,这个解决方案似乎只有在使用“gouraud”着色时才有效(否则,它在推断脸部颜色方面做得很差;见下文)。

诀窍是创建一个颜色映射,当给定n01(包括这两个值)之间的n会重新生成原始的颜色数组:

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))

同样,请注意,'gouraud'底纹是这项工作所必需的。为了说明失败的原因,下面的代码块显示了我的特定用例。(我正在绘制一部分带有部分透明数据覆盖的扁平皮层薄片)。在这段代码中,有40886个顶点(在the_map.coordinates)和81126个三角形(在the_map.indexed_faces)中;colors数组的形状是(40886, 3)

以下代码适用于“gouraud”底纹:

^{pr2}$

Plot using Gouraud shading

但是,如果没有“gouraud”明暗处理,面部颜色可能是根据顶点的平均值分配的(尚未验证这一点),这显然是错误的:

plt.figure(figsize=(16,16))
plt.tripcolor(tri, zs, cmap=cmap)

enter image description here

而对于tripcolor函数,必须使用colormap,它内部调用的PolyCollection和{}类(来自matplotlib.collection)也可以处理RGB颜色数组。{1{cdb>基于给定的源代码绘制三角形^ 1:

tri = Triangulation(...)
colors = nx3 RGB array
maskedTris = tri.get_masked_triangles()
verts = np.stack((tri.x[maskedTris], tri.y[maskedTris]), axis=-1)
collection = PolyCollection(verts)
collection.set_facecolor(colors)
plt.gca().add_collection(collection)
plt.gca().autoscale_view()

要设置每个顶点的颜色(Gouraud着色),请改用TriMesh(与set_facecolor一起使用)。

创建颜色贴图的一种更简单的方法是通过^{}

z = numpy.arange(n)
cmap = matplotlib.colors.LinearSegmentedColormap.from_list(
    'mymap', rgb, N=len(rgb)
    )

相关问题 更多 >

    热门问题