Vispy surface plot highlight particular section with color and image

Question:

Question 1: I am trying to highlight particular section from Vispy Surface Plot example in a particular colour somewhat similar to below modified image.

yellow colour highlight at centre of X-axis

Question 2: Similarly I would like to add an image data as overlay texture to the Vispy surface plot

enter image description here

Can SurfacePlotVisual be used for this?
I am unable to find any examples of the SurfacePlotVisual on the internet.

Can anyone please direct me to the efficient way of getting it done using vispy.
Thanks

Update 1:
Adding Sample code for testing

import sys
import numpy as np

from vispy import app, scene, color
from vispy.util.filter import gaussian_filter
from vispy.visuals.filters import TextureFilter
from vispy.io import imread, load_data_file, read_mesh


canvas = scene.SceneCanvas(keys='interactive', bgcolor='w')
view = canvas.central_widget.add_view()
view.camera = scene.TurntableCamera(up='z', fov=60)

# Simple surface plot example
# x, y values are not specified, so assumed to be 0:50
z = np.random.normal(size=(250, 250), scale=200)
z[100, 100] += 50000
print(z.shape)
z = gaussian_filter(z, (10, 10))


p1 = scene.visuals.SurfacePlot(z=z)  # , color=(0.3, 0.3, 1, 1))
p1.transform = scene.transforms.MatrixTransform()
p1.transform.scale([1 / 249., 1 / 249., 1 / 249.])
p1.transform.translate([-0.5, -0.5, 0])

#verts = p1._meshdata.get_vertices()
verts = p1._meshdata.get_vertices()[:, :2]

texcoords = (verts - verts.min()) / (verts.max() - verts.min())

texture = imread('spot.png')
texture = np.flip(texture, 0) // flip added to get correct position of the image
print("spot.shape:", texture.shape)
print("textcoords:", texcoords)
texture_filter = TextureFilter(texture, texcoords)
p1.attach(texture_filter)

view.add(p1)

xax = scene.Axis(pos=[[-0.5, -0.5], [0.5, -0.5]], tick_direction=(0, -1),
                 font_size=16, axis_color='k', tick_color='k', text_color='k',
                 parent=view.scene)
xax.transform = scene.STTransform(translate=(0, 0, -0.2))

yax = scene.Axis(pos=[[-0.5, -0.5], [-0.5, 0.5]], tick_direction=(-1, 0),
                 font_size=16, axis_color='k', tick_color='k', text_color='k',
                 parent=view.scene)
yax.transform = scene.STTransform(translate=(0, 0, -0.2))

# Add a 3D axis to keep us oriented
axis = scene.visuals.XYZAxis(parent=view.scene)

if __name__ == '__main__':
    canvas.show()
    if sys.flags.interactive == 0:
        app.run()


Update 2:

Have updated above code and output image for reference.

SurfacePlot output with Texture Filter Image

Surface plot output is as above…
Would like to remove surface plot shade and instead would like to have same color output for the surface plot output as compared to image….

Asked By: ViNOJ

||

Answers:

Answer 1

The set_data method of the SurfacePlotVisual takes an array of colors:

https://github.com/vispy/vispy/blob/df6c6be9c5aa6a67abf7e3072780264886e2be77/vispy/visuals/surface_plot.py#L132-L151

You should be able to pass whatever colors you want to that as an RGBA array (MxNx4). Note these are colors for the vertices apparently (based on the code I’m seeing) so colors will be interpolated between vertices.

Answer 2

The SurfacePlot is a subclass of the MeshVisual which is able to have a TextureFilter applied to it. I’ve never done it, but theoretically you should be able to follow this example to add a texture to your SurfacePlot:

https://vispy.org/gallery/scene/mesh_texture.html

The key parts are the loading of the image data from spot.png and then creating and attaching the TextureFilter.

Update 1

Here’s what I get if I change the texcoords line to:

verts = p1._meshdata.get_vertices()[:, :2]

spots on surface plot

Kind of creepy. The point is that we’re just making an array that maps the individual surface plot verticies (the mesh vertices) to points on the image. These coordinates need to be between 0 and 1. So we’re cheating and taking the vertex coordinates of the mesh and normalizing them between 0 and 1. This may not be anything like what you want, but the point is we have texcoords with a shape of (N, 2) where N is the number of mesh vertices and an (x, y) coordinate for each.

Answered By: djhoese
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.