首页 > 解决方案 > 如何在没有中间视图的情况下立即更新 ipyvolume 形状

问题描述

给定 jupyter notebook 具有使用 ipyvolume 渲染的场景和更新场景中形状的 x、y、z 特征的滑块,3D 渲染器具有场景更改动画,该动画绘制形状的中间视图,这些视图与视图上的视图不对应滑块。

如何强制 ipyvolume 在更新时仅渲染最终场景,而不渲染场景更改动画?

例如,在 jupyter notebook 中运行以下命令并拖动 theta/phi:

import numpy as np
from numpy import pi, sin, cos, radians
import ipyvolume as ipv
import ipywidgets as widgets

def transform_xyz(theta, phi, x, y, z):
    x, y, z = [np.asarray(v) for v in (x, y, z)]
    shape = x.shape
    points = np.matrix([x.flatten(), y.flatten(), z.flatten()])
    Ry_theta = [[+cos(theta), 0, +sin(theta)],
                [0, 1, 0],
                [-sin(theta), 0, +cos(theta)]]
    Rz_phi = [[+cos(phi), -sin(phi), 0],
              [+sin(phi), +cos(phi), 0],
              [0, 0, 1]]
    points = np.matrix(Rz_phi)*np.matrix(Ry_theta)*points
    x, y, z = [np.array(v).reshape(shape) for v in points]
    return x, y, z

def torus(R=100, r=10, Rsteps=100, rsteps=100):
    u = np.linspace(0, 2*pi, rsteps) # tube
    v = np.linspace(0, 2*pi, Rsteps) # ring
    U, V = np.meshgrid(u, v)
    x = (R + r*cos(U))*cos(V)
    y = (R + r*cos(U))*sin(V)
    z = r*sin(U)
    return x, y, z

class Scene:
    def __init__(self, view=(0, 0, 0), hkl=(1,1,1)):
        self.view = view
        self.figure = ipv.figure()
        R = 100.
        r = R/30.
        ipv.xlim(-R, R)
        ipv.ylim(-R, R)
        ipv.zlim(-R, R)
        ipv.style.box_off()
        self.torus_xyz = torus(R=R, r=R/10)
        self.torus = ipv.plot_surface(*self.torus_xyz)
        ipv.show()
        self.ui = widgets.interact(self.update, theta=(-90.,90.), phi=(-180., 180.))
        #self.ui.widget.children[0].continuous_update = False
        #self.ui.widget.children[1].continuous_update = False

    def update(self, theta, phi):
        print("update with", theta, phi)
        x, y, z = transform_xyz(radians(theta), radians(phi), *self.torus_xyz)
        self.torus.x = x.flatten()
        self.torus.y = y.flatten()
        self.torus.z = z.flatten()

scene = Scene()

在此处输入图像描述

标签: pythonthree.jsjupyter-notebookipywidgets

解决方案


在创建图形时将过渡的动画时间设置为零主要可以解决问题:

...
self.figure = ipv.figure(animation=0.)
...

当 ui 滑块设置为连续更新时,图形仍然有些抖动,大概是因为正在绘制偶尔的过渡帧。


另一个可能的抖动来源是 traitlets 没有同步发送 x、y、z 更新,因此有时它可能会在新视图中显示 x 和 y 的更新,同时保留旧视图中的 z。


推荐阅读