如何解决在Vispy中的特定位置绘制球体
我在Vispy中有一个3D散点图,其中每个点代表一个数据样本。为了这个问题,我使用了一些虚假数据。当我单击某个点时,它会更改为白色,以显示当前选中的点。
我停留的部分:我想在所选点的顶部绘制一个透明的球体。但是以某种方式,我无法正确地将球体放置在所需位置。
我的例子:
import numpy as np
from vispy import app,visuals,scene,color
from sklearn.manifold import TSNE
import matplotlib.cm as cm
from vispy.visuals.transforms import STTransform
class Visualizer():
def __init__(self):
# fake data
self.data = np.random.normal(0,1,(100,3))
print(self.data.shape)
self.colors = cm.rainbow(np.linspace(0,self.data.shape[0]))
self.init_colors = cm.rainbow(np.linspace(0,self.data.shape[0]))
self.canvas = np.zeros((480,640))
def distance_traveled(self,positions):
"""
Return the total amount of pixels traveled in a sequence of pixel
`positions`,using Manhattan distances for simplicity.
"""
return np.sum(np.abs(np.diff(positions,axis=0)))
def scatter3d(self,positions,colors,symbol='o',size=12,click_radius=2,on_click=None):
"""
Create a 3D scatter plot window that is zoomable and rotateable,with
markers of a given `symbol` and `size` at the given 3D `positions` and in
the given RGBA `colors`,formatted as numpy arrays of size Nx3 and Nx4,respectively. Takes an optional callback function that will be called with
the index of a clicked marker and a reference to the Markers visual
whenever the user clicks a marker (or at most `click_radius` pixels next to
a marker).
"""
# based on https://github.com/vispy/vispy/issues/1189#issuecomment-198597473
# create canvas
canvas = scene.SceneCanvas(keys='interactive',show=True,bgcolor='gray')
# create viewbox for user interaction
view = canvas.central_widget.add_view()
view.camera = 'turntable'
view.camera.fov = 45
view.camera.distance = abs(positions).max() * 2.5
# create visuals
p1 = scene.visuals.Markers(parent=view.scene)
p1.set_gl_state('translucent',blend=True,depth_test=True)
# axis = scene.visuals.XYZAxis(parent=view.scene)
# set positions and colors
kwargs = dict(symbol=symbol,size=size,edge_color=None)
p1.set_data(positions,face_color=self.colors,**kwargs)
print(p1._data)
print(positions)
# prepare list of unique colors needed for picking
ids = np.arange(1,len(positions) + 1,dtype=np.uint32).view(np.uint8)
ids = ids.reshape(-1,4)
ids = np.divide(ids,255,dtype=np.float32)
# connect events
if on_click is not None:
def on_mouse_release(event):
if event.button == 1 and self.distance_traveled(event.trail()) <= 2:
# vispy has some picking functionality that would tell us
# whether any of the scatter points was clicked,but we want
# to know which point was clicked. We do an extra render pass
# of the region around the mouseclick,with each point
# rendered in a unique color and without blending and
# antialiasing.
pos = canvas.transforms.canvas_transform.map(event.pos)
try:
p1.update_gl_state(blend=False)
p1.antialias = 0
p1.set_data(positions,face_color=ids,**kwargs)
img = canvas.render((pos[0] - click_radius,pos[1] - click_radius,click_radius * 2 + 1,click_radius * 2 + 1),bgcolor=(0,0))
finally:
p1.update_gl_state(blend=True)
p1.antialias = 1
p1.set_data(positions,**kwargs)
# We pick the pixel directly under the click,unless it is
# zero,in which case we look for the most common nonzero
# pixel value in a square region centered on the click.
idxs = img.ravel().view(np.uint32)
idx = idxs[len(idxs) // 2]
if idx == 0:
idxs,counts = np.unique(idxs,return_counts=True)
idxs = idxs[np.argsort(counts)]
idx = idxs[-1] or (len(idxs) > 1 and idxs[-2])
# call the callback function
if idx > 0:
# subtract one; color 0 was reserved for the background
on_click(idx - 1,p1)
sphere = scene.visuals.Sphere(radius=0.2,rows=10,cols=10,depth=10,method='cube',parent=view.scene,edge_color='black')
# The problematic line
sphere.transform = STTransform(translate=self.data[idx])
canvas.events.mouse_release.connect(on_mouse_release)
# run application
app.run()
def run(self):
def on_click(idx,markers):
self.colors = self.init_colors.copy()
self.colors[idx] = (1,1)
markers.set_data(self.data,edge_color=None)
self.scatter3d(self.data,self.colors,on_click=on_click)
visualizer = Visualizer()
visualizer.run()
在此示例中,我使用numpy创建了一堆随机数据并将其绘制。但是我不知道如何正确地变换所选点的坐标以在其上方绘制球体。 Vispy的set_data()
在这些点上执行哪些转换?
我试图用canvas.transforms.canvas_transform.map()
变换点,但这是不正确的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。