How to set face color per triangle when using plot_trisurf in PyPlot

question
plotting

#1

Hi, I want to set the face color of each triangle individually when plotting with plot_trisurf in PyPlot. The matplotlib manual seems to indicate that face color is set with the option ‘color’ (as a tuple), but there is also an optional argument ‘facecolor’ that is passed to Poly3DCollection. However, I cannot figure out how to apply this so that each triangle (patch) gets a separately defined color. I do manage to set the edge colors separately using the argument ‘edgecolor’.

This produces the result when all triangles (only two here) get the same color:

using PyPlot
fig  = figure()
ax   = Axes3D(fig)
x    = [0., 1., 1., 0.]
y    = [0., 0.5, 1., 1.]
z    = [0., 0., 1., 0.2]
t    = [1 2 4; 2 3 4]-1 # Zero-based indexing required (?)
fclr = [1. 0. 0.; 0. 0. 1.]
c    = (0.,1.,0.)
plot_trisurf(x,y,z,triangles=t,color=c,edgecolor=fclr,alpha=0.8, linewidth=3.);

I have not managed to get any effect by setting the ‘facecolor’ argument and I don’t know the syntax for passing multiple colors to ‘color’.

Any pointers to where I can find documentation about this, i.e., plotting surfaces with individually defined triangles, without resorting to a loop “over the triangles”?

Tested with v. 0.5.2 and 0.6.0.


#2

I tried to do the same thing. At the time browsing through the matplotlib source lead me to a line saying ‘todo: support facecolors’. Gave up at that point. Not sure what the status is now.

I succeeded in making a coloured mesh plot using PlotlyJs though.


#3

Thanks,

using PlotlyJS.jl I managed to set the face colors individually! But with this solution I don’t know how to set the edge colors… :slight_smile:

The code that gives me (sort of) what I want:

using PlotlyJS
function triplot(vertices,faces,facecolor;opacity=0.5,cameraEye=[-1 -1 1])
    fcStr = [@sprintf("rgb(%5.2f,%5.2f,%5.2f)",255*facecolor[k,1],255*facecolor[k,2],255*facecolor[k,3]) for k = 1:size(facecolor,1) ]
    t = mesh3d(
        x = vertices[:,1], y = vertices[:,2], z = vertices[:,3],
        i = faces[:,1]-1,  j = faces[:,2]-1,  i = faces[:,3]-1, # Zero-based indexing in plotly
        facecolor=fcStr,opacity=opacity)
        layout = Layout(;title="Basic Triangle Plot",
                        scene=attr(;camera=attr(eye=attr(x=cameraEye[1],y=cameraEye[2],z=cameraEye[3]))))
    plot(t, layout)
end

verts = [0. 0. 0.;  1. 0.5 0.; 1. 1. 1.; 0. 1. 0.2]
faces = [1 2 4; 2 3 4]
fclr  = [1. 0. 0.; 0. 0. 1.]
triplot(verts,faces,fclr)

A step in the right direction.


#4

On further inspection, this is a non-working MWE. The triangle indexing appears to have no impact (incorrect syntax?) and the triangles are not colored in the given order. Any ideas would be appreciated. Another graphics package?


#5

This is how I use PlotlyJs. As far as i know it works as expected: https://github.com/krcools/CompScienceMeshes.jl/blob/master/examples/plotlyjs_patches.jl


#6

Thanks, it does work as expected now! I had a typo in the code above (not assigning any values to ‘k’). Vacation can be productive… :slight_smile:


#7

So I’m really new to Python (starting playing around today!) but I think I found a fix. Just put

        if 'facecolors' in kwargs:
            fcolors = kwargs.pop('facecolors')
            polyc.sets_facecolors(fcolors)

at line 2032 and it should work if you use facecolor as an input argument to plot_trisurf. Just make sure you format the input colour array correctly and you’ll be dandy!

I know this is editing the library functions and that can be dubious, but if it works…


#8

You can do it using set_array, see this stack thread