# Gradient-Coloring Vertices Based on Global Z-Loc Not Working As Expected

I tried to write my own code that changes vertex colors based on the vertex Z-location(global). Which I derived from these links:

How can I get vertex positions from a mesh?

https://blenderartists.org/t/setting-vertex-color-via-python/481060/5

https://blenderartists.org/t/meshvertex-co-vertex-position-issue/670866

The base code looks like this:

from bpy import *
from random import *

bpy.context.scene.update()

#obj = context.active_object.
obj = data.objects["Cube"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data

for v in verts:
vertZloc = ((obj.matrix_world  * v.co)[2])
#print(vertZloc) # for sanity check
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)
vColour = [(redMod,grnMod,0) for i in mesh.vertices]
# asign colours to verts
for i in range(len(faces)):
v = vertexColour[i]
f = faces[i].vertices
#print('\n'.join(map(str, faces[i].vertices))) # sanity check
v.color = vColour[f[0]]
v.color = vColour[f[1]]
v.color = vColour[f[2]]
v.color = vColour[f[3]]

When I ran a longer version of my code to change the vertex coloring of 5 'cubes' of different heights, I found that any "between" heights have the same color, when there should be a linear correlation to the height and green/red values.

Why is this? My formulae are both linear plots:

vertZloc = ((obj.matrix_world  * v.co)[2])
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)

Stretch Help:

Also as a side note, I do want the all the top-vertex colors to change, not just the two vertices of the top plane, but I have not tried to solve that yet, I have just been focusing on the coloring function.

EDIT:

My full code, in case it is wanted, although it shouldn't explain anything else:

from bpy import *
from random import *

bpy.context.scene.update()

#obj = context.active_object.
obj = data.objects["Cube"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data

for v in verts:
vertZloc = ((obj.matrix_world  * v.co)[2])
#print(vertZloc) # for sanity check
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)
vColour = [(redMod,grnMod,0) for i in mesh.vertices]
# asign colours to verts
for i in range(len(faces)):
v = vertexColour[i]
f = faces[i].vertices
#print('\n'.join(map(str, faces[i].vertices))) # sanity check
v.color = vColour[f[0]]
v.color = vColour[f[1]]
v.color = vColour[f[2]]
v.color = vColour[f[3]]

################### CUBE 1

#obj = context.active_object.
obj = data.objects["Cube.001"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data

for v in verts:
vertZloc = ((obj.matrix_world  * v.co)[2])
#print(vertZloc) # for sanity check
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)
vColour = [(redMod,grnMod,0) for i in mesh.vertices]
# asign colours to verts
for i in range(len(faces)):
v = vertexColour[i]
f = faces[i].vertices
#print('\n'.join(map(str, faces[i].vertices))) # sanity check
v.color = vColour[f[0]]
v.color = vColour[f[1]]
v.color = vColour[f[2]]
v.color = vColour[f[3]]

################### CUBE 2

#obj = context.active_object.
obj = data.objects["Cube.002"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data

for v in verts:
vertZloc = ((obj.matrix_world  * v.co)[2])
#print(vertZloc) # for sanity check
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)
vColour = [(redMod,grnMod,0) for i in mesh.vertices]
# asign colours to verts
for i in range(len(faces)):
v = vertexColour[i]
f = faces[i].vertices
#print('\n'.join(map(str, faces[i].vertices))) # sanity check
v.color = vColour[f[0]]
v.color = vColour[f[1]]
v.color = vColour[f[2]]
v.color = vColour[f[3]]

################### CUBE 3

#obj = context.active_object.
obj = data.objects["Cube.003"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data

for v in verts:
vertZloc = ((obj.matrix_world  * v.co)[2])
#print(vertZloc) # for sanity check
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)
vColour = [(redMod,grnMod,0) for i in mesh.vertices]
# asign colours to verts
for i in range(len(faces)):
v = vertexColour[i]
f = faces[i].vertices
#print('\n'.join(map(str, faces[i].vertices))) # sanity check
v.color = vColour[f[0]]
v.color = vColour[f[1]]
v.color = vColour[f[2]]
v.color = vColour[f[3]]

################### CUBE 4

#obj = context.active_object.
obj = data.objects["Cube.004"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data

for v in verts:
vertZloc = ((obj.matrix_world  * v.co)[2])
#print(vertZloc) # for sanity check
redMod = (28.3333333 * (vertZloc) - 28.3333333)
grnMod = (-(28.3333333 * (vertZloc)) + 283.3333333)
vColour = [(redMod,grnMod,0) for i in mesh.vertices]
# asign colours to verts
for i in range(len(faces)):
v = vertexColour[i]
f = faces[i].vertices
#print('\n'.join(map(str, faces[i].vertices))) # sanity check
v.color = vColour[f[0]]
v.color = vColour[f[1]]
v.color = vColour[f[2]]
v.color = vColour[f[3]]

By adding 2 subdivisions to each cube, I was able to get full spectrum coloring with the code below:

import bpy
from collections import defaultdict

obj = bpy.data.objects["Cube"]
mesh = obj.data
verts = mesh.vertices
faces = mesh.polygons
vertexColour = mesh.vertex_colors[0].data
mHeight = 10
redMod = 0
bluMod = 0
grnMod = 0
step = (255 / mHeight)
index = 0

vcol_layer = mesh.vertex_colors.active

# create map of vertices to loop indices
vertex_map = defaultdict(list)
for poly in faces:
for v_ix, l_ix in zip(poly.vertices, poly.loop_indices):
vertex_map[v_ix].append(l_ix)

# reverses the dictionary access
def get_key(val, my_dict):
for key, value in my_dict.items():
for subvalue in value:
if val == subvalue:
return key

for poly in faces:
for loop_index in poly.loop_indices:
v = verts[get_key(loop_index, vertex_map)]
vertZloc = ((obj.matrix_world  * v.co)[2])
p = (vertZloc / mHeight)
if p > .75:
redMod = 1.0
grnMod = (1 - ((p-.75)*4))
bluMod = 0
elif .75 >= p >= .50:
redMod = ((p-.5)*4)
grnMod = 1.0
bluMod = 0
elif .5 > p > .25:
redMod = 0
grnMod = 1.0
bluMod = (1 - ((p - .25) * 4))
else:
redMod = 0
grnMod = ((p)*4)
bluMod = 1.0
color = ( redMod, grnMod, bluMod)
#loop_vert_index = mesh.loops[loop_index].vertex_index
vcol_layer.data[loop_index].color = color
index = index+1