Replies: 4 comments
-
Hi have you looked into In principle you should be able to pass a |
Beta Was this translation helpful? Give feedback.
-
Thanks @marcomusy I got what I wanted with your suggestion of build_lut and I included some code below in case it is helpful for others. for e.g. a complicated colormap based on mesh point height (adapted from https://github.com/marcomusy/vedo/blob/master/examples/basic/mesh_custom.py): from vedo import *
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import numpy as np
man = Mesh(dataurl + "man.vtk")
h_knees = -0.5
# let the scalar be the z coordinate of the mesh vertices
scals = man.vertices[:, 2]
# build a complicated colour map
c1 = plt.cm.viridis(np.linspace(0.0, 0.7, 128))
c2 = plt.cm.terrain(np.linspace(0.5, 0.8, 128))
c = np.vstack((c1, c2))
cmap = colors.LinearSegmentedColormap.from_list("heights", c)
norm = colors.TwoSlopeNorm(h_knees)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=cmap)
# build look up table
vmin = min(scals)
vmax = max(scals)
lut = build_lut([(v, mapper.to_rgba(v)[:3]) for v in np.linspace(vmin, vmax, 100)])
man.cmap(lut, scals, on="points")
man.add_scalarbar()
show(man) I still haven't worked out how to preserve other cmap properties e.g. set_over(). But this can be set directly in build_lut's above_color parameter. |
Beta Was this translation helpful? Give feedback.
-
Consider also this option: from vedo import *
import matplotlib.colors as colors
import matplotlib.pyplot as plt
settings.default_font = "Antares"
man = Mesh(dataurl + "man.vtk")
h_knees = -0.5
# let the scalar be the z coordinate of the mesh vertices
scals = man.vertices[:, 2]
# build a complicated colour map
c1 = plt.cm.viridis(np.linspace(0.0, 0.7, 128))
c2 = plt.cm.terrain(np.linspace(0.5, 0.8, 128))
c = np.vstack((c1, c2))
cmap = colors.LinearSegmentedColormap.from_list("heights", c)
norm = colors.TwoSlopeNorm(h_knees)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=cmap)
# build look up table
vmin = min(scals)
vmax = max(scals)
lut = build_lut(
[(v, mapper.to_rgba(v)[:3]) for v in np.linspace(vmin, vmax, 100)],
above_color="red5",
below_color="orange6",
vmin=vmin+0.1,
vmax=vmax-0.1,
)
man.cmap(lut, scals)
man.add_scalarbar3d(above_text="Above Eyes", below_text="Below Heels")
man.scalarbar = man.scalarbar.clone2d("center-left", size=0.3) # make it 2D
show(man, axes=1, viewup="z") |
Beta Was this translation helpful? Give feedback.
-
And finally: carrying all the values from the matplotlib object; being explicit in where the over and under limits are; and better defining the 'norm': from vedo import *
import matplotlib.colors as colors
import matplotlib.pyplot as plt
settings.default_font = "Antares"
man = Mesh(dataurl + "man.vtk")
h_knees = -0.5
over_limit = 1.5
under_limit = -1.4
# let the scalar be the z coordinate of the mesh vertices
scals = man.vertices[:, 2]
# build a complicated colour map
c1 = plt.cm.viridis(np.linspace(0.0, 0.7, 128))
c2 = plt.cm.terrain(np.linspace(0.5, 0.8, 128))
c = np.vstack((c1, c2))
cmap = colors.LinearSegmentedColormap.from_list("heights", c)
cmap.set_over(color="red")
cmap.set_under(color="orange")
norm = colors.TwoSlopeNorm(h_knees, vmin=under_limit, vmax=over_limit)
mapper = plt.cm.ScalarMappable(norm=norm, cmap=cmap)
# build look up table
vmin = min(scals)
vmax = max(scals)
lut = build_lut(
[(v, mapper.to_rgba(v)[:3]) for v in np.linspace(under_limit, over_limit, 100)],
above_color=cmap.get_over()[:3],
below_color=cmap.get_under()[:3],
vmin=under_limit,
vmax=over_limit,
)
man.cmap(lut, scals)
man.add_scalarbar3d(above_text="Above Eyes", below_text="Below Heels")
man.scalarbar = man.scalarbar.clone2d("center-left", size=0.3) # make it 2D
show(man, axes=1, viewup="z") |
Beta Was this translation helpful? Give feedback.
-
Hello, thanks for this powerful module. I am finding it very useful.
I have a question regarding custom colour maps. I am creating my own colour maps via matplotlib (creating a cmap and norm - then creating a mapper e.g. cm.ScalarMappable) I then apply this mapper to generate a list of colours per cell to directly edit e.g. mesh.cellcolors in vedo. Which all works as I would like.
I would like to show a scalarbar in the visualisation with this custom colour map.
I guess the vedo method would be to colour the mesh with .cmap (instead of editing mesh.cellcolors directly) and then .add_scalarbar() would be perfect, however I cant find a way to pass the details of my colormap to this function.
Is there a way to pass a ScalarMappable object (or norm and cmap) to .cmap? If not - maybe to bypass this and directly create a custom scalarbar with my colormap?
Many thanks
Beta Was this translation helpful? Give feedback.
All reactions