Esempio n. 1
0
def plot_box(corner1=(0.1, 0.1, 0.1), corner2=(0.5, 0.5, 0.5), color='red'):
    c1 = np.array(corner1)
    c2 = np.array(corner2)
    c = np.stack([c1, c2])

    points = np.array([
        [c[0, 0], c[0, 1], c[0, 2]],
        [c[1, 0], c[0, 1], c[0, 2]],
        [c[1, 0], c[1, 1], c[0, 2]],
        [c[0, 0], c[1, 1], c[0, 2]],
        [c[0, 0], c[0, 1], c[1, 2]],
        [c[1, 0], c[0, 1], c[1, 2]],
        [c[1, 0], c[1, 1], c[1, 2]],
        [c[0, 0], c[1, 1], c[1, 2]],
    ])

    x = points[:, 0]
    y = points[:, 1]
    z = points[:, 2]

    lines = [
        [0, 1],
        [1, 2],
        [2, 3],
        [3, 0],
        [4, 5],
        [5, 6],
        [6, 7],
        [7, 4],
        [0, 4],
        [1, 5],
        [2, 6],
        [3, 7],
    ]
    ipv.plot_trisurf(x, y, z, lines=lines, color=color)
Esempio n. 2
0
def show_mesh(vertices,
              faces,
              color='green',
              width=500,
              height=500,
              colors=None):

    ipyvolume.figure(width=width, height=height)
    ipyvolume.view(0, 90)
    ipyvolume.plot_trisurf(vertices[:, 0],
                           vertices[:, 1],
                           vertices[:, 2],
                           triangles=faces,
                           color=color)

    x_min = vertices[:, 0].min()
    x_max = vertices[:, 0].max()
    y_min = vertices[:, 1].min()
    y_max = vertices[:, 1].max()
    z_min = vertices[:, 2].min()
    z_max = vertices[:, 2].max()

    xyz_max = max(x_max - x_min, y_max - y_min, z_max - z_min)

    ipyvolume.xlim(x_min, x_min + xyz_max)
    ipyvolume.ylim(y_min, y_min + xyz_max)
    ipyvolume.zlim(z_min, z_min + xyz_max)

    ipyvolume.show()
Esempio n. 3
0
    def data_points(buttons, drop):
        ipv.figure()
        ipv.scatter(all_pt[0],
                    all_pt[1],
                    all_pt[2],
                    size=2,
                    marker='sphere',
                    color='red')
        for i in range(len(traces)):
            pairs = traces[i]['pairs']
            ipv.plot_trisurf(all_pt[0], all_pt[1], all_pt[2], lines=pairs)
        if drop != None:
            if buttons == 'Analysis':
                x = pt55[in_names55[drop]][0]
                y = pt55[in_names55[drop]][1]
                z = pt55[in_names55[drop]][2]
                ipv.scatter(x, y, z, size=3, color='blue', marker='circle_2d')
            if buttons == 'Function data':
                x = pt58[in_names58[drop]][0]
                y = pt58[in_names58[drop]][1]
                z = pt58[in_names58[drop]][2]
                ipv.scatter(x, y, z, size=3, color='blue', marker='circle_2d')

        ipv.xlim(min(all_pt[0]) - 1, max(all_pt[0]) + 1)
        ipv.ylim(min(all_pt[1]) - 1, max(all_pt[1]) + 1)
        ipv.zlim(min(all_pt[2]) - 1, max(all_pt[2]) + 1)
        ipv.show()
Esempio n. 4
0
 def init_plane(self, z):
     "Plot plane for the first time. From ipw.plot_trisurf.__doc__"
     ipv.plot_trisurf(
         [0,0,1,1],
         [0,1,0,1],
         [z,z,z,z],
         triangles=[[0, 2, 3], [0, 3, 1]],
     )
Esempio n. 5
0
def brain(draw=True, show=True, fiducial=True, flat=True, inflated=True, subject='S1', interval=1000, uv=True, color=None):
    import ipyvolume as ipv
    try:
        import cortex
    except:
        warnings.warn("it seems pycortex is not installed, which is needed for this example")
        raise
    xlist, ylist, zlist = [], [], []
    polys_list = []
    def add(pts, polys):
        xlist.append(pts[:,0])
        ylist.append(pts[:,1])
        zlist.append(pts[:,2])
        polys_list.append(polys)
    def n(x):
        return (x - x.min()) / x.ptp()
    if fiducial or color is True:
        pts, polys = cortex.db.get_surf('S1', 'fiducial', merge=True)
        x, y, z = pts.T
        r = n(x)
        g = n(y)
        b = n(z)
        if color is True:
            color = np.array([r,g,b]).T.copy()
        else:
            color = None
        if fiducial:
            add(pts, polys)
    else:
        if color is False:
            color = None
    if inflated:
        add(*cortex.db.get_surf('S1', 'inflated', merge=True, nudge=True))
    u = v = None
    if flat or uv:
        pts, polys = cortex.db.get_surf('S1', 'flat', merge=True, nudge=True)
        x, y, z = pts.T
        u = n(x)
        v = n(y)
        if flat:
            add(pts, polys)

    polys_list.sort(key=lambda x: len(x))
    polys = polys_list[0]
    if draw:
        if color is None:
            mesh = ipv.plot_trisurf(xlist, ylist, zlist, polys, u=u, v=v)
        else:
            mesh = ipv.plot_trisurf(xlist, ylist, zlist, polys, color=color, u=u, v=v)
        if show:
            if len(x) > 1:
                ipv.animation_control(mesh, interval=interval)
            ipv.squarelim()
            ipv.show()
        return mesh
    else:
        return xlist, ylist, zlist, polys
Esempio n. 6
0
def show_syntehtic_plant(vertices,
                         faces,
                         meta_data=None,
                         size=0.5,
                         color='green',
                         width=500,
                         height=500):

    ipyvolume.figure(width=width, height=height)
    ipyvolume.view(0, 90)

    ipyvolume.plot_trisurf(vertices[:, 0],
                           vertices[:, 1],
                           vertices[:, 2],
                           triangles=faces,
                           color=color)

    voxels_position = vertices
    if meta_data is not None:
        ranks = meta_data['leaf_order']
        polylines = {
            n:
            list(map(numpy.array, list(zip(*meta_data['leaf_polylines'][i]))))
            for i, n in enumerate(ranks)
        }

        voxels = set()
        for leaf_order in polylines:
            x, y, z, r = polylines[leaf_order]
            polyline = numpy.array(list(zip(x, y, z))) * 10 - \
                       numpy.array([0, 0, 750])

            plot_voxel(polyline, size=size, color="red")
            voxels = voxels.union(set(map(tuple, list(polyline))))

        voxels = voxels.union(set(map(tuple, list(voxels_position))))
        voxels_position = numpy.array(list(voxels), dtype=numpy.int)

    x_min = voxels_position[:, 0].min()
    x_max = voxels_position[:, 0].max()
    y_min = voxels_position[:, 1].min()
    y_max = voxels_position[:, 1].max()
    z_min = voxels_position[:, 2].min()
    z_max = voxels_position[:, 2].max()
    xyz_max = max(x_max - x_min, y_max - y_min, z_max - z_min)
    ipyvolume.xlim(x_min, x_min + xyz_max)
    ipyvolume.ylim(y_min, y_min + xyz_max)
    ipyvolume.zlim(z_min, z_min + xyz_max)

    ipyvolume.show()
Esempio n. 7
0
def plot_line(p1=(0, 0, 0), p2=(1, 1, 1), color='red'):
    p1 = np.array(p1)
    p2 = np.array(p2)
    points = np.stack([p1, p2])
    print(points.shape)

    x = points[:, 0]
    y = points[:, 1]
    z = points[:, 2]

    # draw lines from the first vertex to second
    lines = [[0, 1]]

    ipv.plot_trisurf(x, y, z, lines=lines, color=color)
Esempio n. 8
0
    def _plot_hemi_mesh(self, vertices, faces, color='grey'):
        u"""Plot triangular format Freesurfer surface of the brain hemispheres.

        Parameters
        ----------
        vertices : numpy.array
            Array of vertex (x, y, z) coordinates, of size
            number_of_vertices x 3.
        faces : numpy.array
            Array defining mesh triangles, of size number_of_faces x 3.
        color : str | numpy.array, optional
            Color for each point/vertex/symbol, can be string format,
            examples for red:’red’, ‘#f00’, ‘#ff0000’ or ‘rgb(1,0,0),
            or rgb array of shape (N, 3). Default value is 'grey'.

        Returns
        -------
        mesh_widget : ipyvolume.Mesh
            Ipyvolume object presenting the built mesh.
        """
        x = vertices[:, 0]
        y = vertices[:, 1]
        z = vertices[:, 2]

        mesh = ipv.plot_trisurf(x, y, z, triangles=faces, color=color)

        return mesh
Esempio n. 9
0
def plot_ipv_mesh(elephant_mesh_sub, color=[1., 0., 0., 0.2]):
    mesh4 = ipv.plot_trisurf(elephant_mesh_sub.vertices[:, 0],
                             elephant_mesh_sub.vertices[:, 1],
                             elephant_mesh_sub.vertices[:, 2],
                             triangles=elephant_mesh_sub.faces)

    mesh4.color = color
    mesh4.material.transparent = True
Esempio n. 10
0
def test_ipyvolume():
    import ipyvolume as ipv

    s = 1 / 2**0.5
    # 4 vertices for the tetrahedron
    x = np.array([1., -1, 0, 0])
    y = np.array([0, 0, 1., -1])
    z = np.array([-s, -s, s, s])
    # and 4 surfaces (triangles), where the number refer to the vertex index
    triangles = [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 3, 2)]

    ipv.figure()
    # draw the tetrahedron mesh
    ipv.plot_trisurf(x, y, z, triangles=triangles, color='orange')
    # mark the vertices
    ipv.scatter(x, y, z, marker='sphere', color='blue')
    # set limits and show
    ipv.xyzlim(-2, 2)
    ipv.show()
Esempio n. 11
0
def SaveMeshAsHTML(cell_dir, stl_id, mesh_dir='./'):
    in_mesh = GetMesh(cell_dir, stl_id)
    IX, IY, IZ = 2, 1, 0
    x, y, z = in_mesh.vertices[:,IX].astype(float), \
                in_mesh.vertices[:,IY].astype(float), \
                in_mesh.vertices[:,IZ].astype(float)
    triangles = in_mesh.faces
    ipv.figure()
    mesh = ipv.plot_trisurf(x, y, z, triangles=triangles, color='skyblue')
    ipv.pylab.style.axes_off()
    ipv.pylab.style.box_off()
    ipv.save(os.path.join(mesh_dir, 'mesh' + str(stl_id) + '.html'))
def _add_ray_history(history, config, lost=None):

    if lost is False:
        color = [1.0, 0.0, 0.0, 0.1]
    elif lost is True:
        color = [0.0, 0.0, 1.0, 0.1]
    else:
        color = [0.0, 0.0, 0.0, 0.1]

    num_elem = len(history)
    key_list = list(history.keys())

    for ii in range(num_elem - 1):

        # All rays leaving this optic element.
        mask = history[key_list[ii]]['mask']

        # This is a temporary solution to filter lost rays for
        # which no intersection at the next optic was calculated.
        #
        # This is not a good solution overall since it is possible
        # to imagine a case where we would want to retain rays at
        # the origin.
        mask &= history[key_list[ii + 1]]['origin'][:, 0] != 0.0

        num_mask = np.sum(mask)

        if num_mask == 0:
            continue

        x0 = history[key_list[ii]]['origin'][mask, 0]
        y0 = history[key_list[ii]]['origin'][mask, 1]
        z0 = history[key_list[ii]]['origin'][mask, 2]
        x1 = history[key_list[ii + 1]]['origin'][mask, 0]
        y1 = history[key_list[ii + 1]]['origin'][mask, 1]
        z1 = history[key_list[ii + 1]]['origin'][mask, 2]

        x = np.concatenate((x0, x1))
        y = np.concatenate((y0, y1))
        z = np.concatenate((z0, z1))

        lines = np.zeros((num_mask, 2), dtype=int)
        lines[:, 0] = np.arange(0, num_mask)
        lines[:, 1] = np.arange(num_mask, num_mask * 2)

        obj = ipv.plot_trisurf(x, y, z, lines=lines, color=color)
        obj.line_material.transparent = True
        obj.line_material.linewidth = 10.0
Esempio n. 13
0
def ipv_draw_pose_3d(ipv,
                     R,
                     t,
                     color='blue',
                     camera_scale=0.15,
                     draw_axis_indicate=True):

    # camera obj
    cam_points = np.array([[0, 0, 0], [-1, -1, 1.5], [1, -1, 1.5], [1, 1, 1.5],
                           [-1, 1, 1.5]])
    # axis indicators
    axis_points = np.array([[-0.5, 1, 1.5], [0.5, 1, 1.5], [0, 1.2, 1.5],
                            [1, -0.5, 1.5], [1, 0.5, 1.5], [1.2, 0, 1.5]])
    # transform camera objs...
    cam_points = (camera_scale * cam_points - t).dot(R)
    axis_points = (camera_scale * axis_points - t).dot(R)

    x = cam_points[:, 0]
    y = cam_points[:, 1]
    z = cam_points[:, 2]
    cam_wire_draw_order = np.asarray([
        (0, 1, 4, 0),  # left
        (0, 3, 2, 0),  # right
        (0, 4, 3, 0),  # top
        (0, 2, 1, 0)
    ])  # bottom
    x = np.take(x, cam_wire_draw_order)
    y = np.take(y, cam_wire_draw_order)
    z = np.take(z, cam_wire_draw_order)

    axis_triangles = np.asarray([
        (
            3,
            5,
            4,
        ),  # x-axis indicator
        (0, 1, 2)
    ])  # y-axis indicator

    mesh = ipv.plot_wireframe(x, y, z, color=color, wrapx=True)
    mesh2 = ipv.plot_trisurf(x=axis_points[:, 0],
                             y=axis_points[:, 1],
                             z=axis_points[:, 2],
                             triangles=axis_triangles,
                             color=color)
Esempio n. 14
0
def draw_compas_mesh(mesh, color='white', size=1.0):
    """
    Renders a compas mesh on a 3D canvas with ipyvolume.

    Parameters
    ----------
    mesh : :class: compas.datastructures.Mesh
        the mesh to be shown in 3D

    Returns
    -------
    an instance of ipyvolume.widgets.Mesh
    """
    import ipyvolume as ipv

    # extract lists of vertices and faces
    vertices, faces = mesh.to_vertices_and_faces()

    # extract x, y and z values into separate lists
    x = [v[0] for v in vertices]
    y = [v[1] for v in vertices]
    z = [v[2] for v in vertices]

    # triangulate n-gons
    triangles_only = []
    for f in faces:
        if len(f) == 3:
            triangles_only.append(f)
        else:
            for i in range(len(f) - 2):
                triangles_only.append([f[0], f[i+1], f[i+2]])

    # create the ipyvolume plot
    ipv.figure(width=800, height=450)
    viewermesh = ipv.plot_trisurf(x, y, z, triangles_only, color=color)
    ipv.xyzlim(size)
    ipv.style.use('minimal')
    ipv.show()

    return viewermesh
Esempio n. 15
0
    def _plot_hemi_overlay(self, vertices, faces, color):
        u"""Plot overlay of the brain hemispheres with activation data.

        Parameters
        ----------
        vertices : numpy.array
            Array of vertex (x, y, z) coordinates, of size
            number_of_vertices x 3.
        faces : numpy.array
            Array defining mesh triangles, of size number_of_faces x 3.
        color : str | numpy.array, optional
            Color for each point/vertex/symbol, can be string format,
            examples for red:’red’, ‘#f00’, ‘#ff0000’ or ‘rgb(1,0,0),
            or rgb array of shape (N, 3). Default value is 'grey'.

        Returns
        -------
        mesh_overlay : ipyvolume.Mesh
            Ipyvolume object presenting the built mesh.
        """
        x = vertices[:, 0]
        y = vertices[:, 1]
        z = vertices[:, 2]

        mesh_overlay = ipv.plot_trisurf(x, y, z, triangles=faces, color=color)

        # Tranparency and alpha blending for the new material of the mesh
        mat = ShaderMaterial()
        mat.alphaTest = 0.1
        mat.blending = BlendingMode.CustomBlending
        mat.blendDst = BlendFactors.OneMinusSrcAlphaFactor
        mat.blendEquation = Equations.AddEquation
        mat.blendSrc = BlendFactors.SrcAlphaFactor
        mat.transparent = True
        mat.side = Side.DoubleSide

        mesh_overlay.material = mat

        return mesh_overlay
def add_surf(obj):
    w = obj.param['xsize'] / 2.0
    h = obj.param['ysize'] / 2.0
    d = obj.param['zsize'] / 2.0

    points = np.zeros((8, 3))
    points[0, :] = [w, h, d]
    points[1, :] = [w, -h, d]
    points[2, :] = [-w, h, d]
    points[3, :] = [-w, -h, d]

    points[4, :] = [w, h, -d]
    points[5, :] = [w, -h, -d]
    points[6, :] = [-w, h, -d]
    points[7, :] = [-w, -h, -d]

    points_ext = obj.point_to_external(points)

    x = points_ext[:, 0]
    y = points_ext[:, 1]
    z = points_ext[:, 2]

    # I am sure there is a way to automate this using a meshgrid,
    # but at the moment this is faster.
    if d > 0:
        triangles = ((0, 3, 1), (0, 3, 2), (4, 7, 5), (4, 7, 6), (0, 6, 2),
                     (0, 6, 4), (0, 5, 1), (0, 5, 4), (3, 6, 2), (3, 6, 7),
                     (3, 5, 1), (3, 5, 7))
    else:
        triangles = ((0, 3, 1), (0, 3, 2))

    ipv_obj = ipv.plot_trisurf(x,
                               y,
                               z,
                               triangles=triangles,
                               color=[1.0, 1.0, 0.0, 0.2])
    ipv_obj.material.transparent = True
Esempio n. 17
0
def graph_skeleton_and_mesh(main_mesh_verts=[],
                            main_mesh_faces=[],
                            unique_skeleton_verts_final=[],
                            edges_final=[],
                            edge_coordinates=[],
                            other_meshes=[],
                            other_meshes_colors=[],
                            main_mesh_face_coloring=[],
                            buffer=0,
                            axis_box_off=True,
                            html_path=""):
    """
    Graph the final result: 
    """

    ipv.figure(figsize=(15, 15))

    if (len(unique_skeleton_verts_final) > 0
            and len(edges_final) > 0) or (len(edge_coordinates) > 0):
        if (len(edge_coordinates) > 0):
            unique_skeleton_verts_final, edges_final = convert_skeleton_to_nodes_edges(
                edge_coordinates)
        mesh2 = ipv.plot_trisurf(unique_skeleton_verts_final[:, 0],
                                 unique_skeleton_verts_final[:, 1],
                                 unique_skeleton_verts_final[:, 2],
                                 lines=edges_final,
                                 color='blue')

        mesh2.color = [0, 0., 1, 1]
        mesh2.material.transparent = True

    if len(main_mesh_verts) > 0 and len(main_mesh_faces) > 0:
        main_mesh = trimesh.Trimesh(vertices=main_mesh_verts,
                                    faces=main_mesh_faces)

        mesh3 = ipv.plot_trisurf(main_mesh.vertices[:, 0],
                                 main_mesh.vertices[:, 1],
                                 main_mesh.vertices[:, 2],
                                 triangles=main_mesh.faces)
        mesh3.color = [0., 1., 0., 0.2]
        mesh3.material.transparent = True

        volume_max = np.max(main_mesh.vertices, axis=0)
        volume_min = np.min(main_mesh.vertices, axis=0)

        ranges = volume_max - volume_min
        index = [0, 1, 2]
        max_index = np.argmax(ranges)
        min_limits = [0, 0, 0]
        max_limits = [0, 0, 0]

        for i in index:
            if i == max_index:
                min_limits[i] = volume_min[i] - buffer
                max_limits[i] = volume_max[i] + buffer
                continue
            else:
                difference = ranges[max_index] - ranges[i]
                min_limits[i] = volume_min[i] - difference / 2 - buffer
                max_limits[i] = volume_max[i] + difference / 2 + buffer

        #ipv.xyzlim(-2, 2)
        ipv.xlim(min_limits[0], max_limits[0])
        ipv.ylim(min_limits[1], max_limits[1])
        ipv.zlim(min_limits[2], max_limits[2])

    for curr_mesh, curr_color in zip(other_meshes, other_meshes_colors):
        plot_ipv_mesh(curr_mesh, color=curr_color)

    #will go through and color the faces of the main mesh if any sent
    for face_array, face_color in main_mesh_face_coloring:
        curr_mesh = main_mesh.submesh([face_array], append=True)
        plot_ipv_mesh(curr_mesh, face_color)

    ipv.style.set_style_light()
    if axis_box_off:
        ipv.style.axes_off()
        ipv.style.box_off()
    else:
        ipv.style.axes_on()
        ipv.style.box_on()
    ipv.show()

    if html_path != "":
        print(f"printing to html : {html_path}")
        ipv.pylab.save(html_path)
Esempio n. 18
0
def show_mesh(verts,
              triangles,
              face_colors=None,
              face_labels=None,
              face_cmap=cm.RdBu,
              face_reorder_colors=True,
              vertex_colors=None,
              vertex_labels=None,
              vertex_cmap=cm.RdBu,
              vertex_reorder_colors=True,
              vertex_normals=None,
              point_size_value=0.5,
              vector_size_value=0.5,
              width=800,
              height=600,
              axeslim='auto',
              aspect_ratio_preserve=True,
              verbose=0):
    """
    vertex_normals - normals of vertices.
    """

    if vertex_normals is not None:
        assert len(verts) == len(
            vertex_normals
        ), "Length incorrect. These are not normals of points, may be."

    x = verts[:, 0]
    y = verts[:, 1]
    z = verts[:, 2]

    ipv.figure(width=width, height=height)

    set_axes_lims(verts,
                  axeslim=axeslim,
                  aspect_ratio_preserve=aspect_ratio_preserve)

    # faces
    if face_labels is not None:
        face_color_dict = calc_colors_dict_by_labels(
            face_labels, cmap=face_cmap, reorder_colors=face_reorder_colors)
        for label in face_color_dict.keys():
            triangles_set = triangles[face_labels == label]
            color = face_color_dict[label]
            _ = ipv.plot_trisurf(x, y, z, triangles=triangles_set, color=color)
    else:
        if face_colors is None:
            face_colors = '#f0f0f0'
        _ = ipv.plot_trisurf(x, y, z, triangles=triangles, color=face_colors)

    # vertices
    is_multilabels = isinstance(vertex_labels, (list, tuple))
    if is_multilabels:
        vertex_colors_by_labels = []
        for vl in vertex_labels:
            vertex_colors_by_labels.append(
                calc_colors_by_labels(vl,
                                      cmap=vertex_cmap,
                                      reorder_colors=vertex_reorder_colors))
    else:
        vertex_colors_by_labels = calc_colors_by_labels(
            vertex_labels,
            cmap=vertex_cmap,
            reorder_colors=vertex_reorder_colors)
    vertex_colors_rgb = vertex_colors

    if vertex_colors_by_labels is None and vertex_colors_rgb is None:
        vertex_current_colors = 'red'
    elif vertex_colors_rgb is not None:
        vertex_current_colors = vertex_colors_rgb
    elif is_multilabels:
        vertex_current_colors = vertex_colors_by_labels[0]
    else:
        vertex_current_colors = vertex_colors_by_labels

    sc = ipv.scatter(x,
                     y,
                     z,
                     size=point_size_value,
                     marker='sphere',
                     color=vertex_current_colors)

    point_size = FloatSlider(min=0, max=2, step=0.1, description='Vertex size')
    jslink((sc, 'size'), (point_size, 'value'))

    w_switch_vertex_colors = get_color_switch_widget(vertex_colors_by_labels,
                                                     vertex_colors_rgb, sc)

    widget_list = [ipv.gcc(), point_size]

    # vertex normals
    if vertex_normals is not None:
        u = vertex_normals[:, 0]
        v = vertex_normals[:, 1]
        w = vertex_normals[:, 2]

        quiver = ipv.quiver(x,
                            y,
                            z,
                            u,
                            v,
                            w,
                            size=vector_size_value,
                            marker="arrow",
                            color='green')

        vector_size = FloatSlider(min=0,
                                  max=5,
                                  step=0.1,
                                  description='Nomals size')
        jslink((quiver, 'size'), (vector_size, 'value'))
        widget_list.append(vector_size)

    if w_switch_vertex_colors is not None:
        widget_list.append(w_switch_vertex_colors)

    return display_widgets(widget_list)
Esempio n. 19
0
def plot_brain(brain,
               surface='dots',
               nodes=True,
               node_colors=False,
               node_groups=None,
               surface_color=None,
               node_color='red',
               network=None,
               dot_size=0.1,
               dot_color='gray',
               min_fibers=10,
               max_fibers=500,
               lowest_cmap_color=0.2,
               highest_cmap_color=0.7,
               cmap='rocket',
               background='light'):
    import ipyvolume as ipv

    if surface_color is None:
        if surface == 'dots': surface_color = 'gray'
        elif surface == 'full': surface_color = 'orange'

    if isinstance(node_colors, bool) and node_colors:
        node_colors = ['red', 'green', 'blue', 'violet', 'yellow']

    if node_colors and node_groups is None:
        node_groups = brain['nodes']['label']

    fig = ipv.figure()

    # plot surface
    x, y, z = [brain['surface'][key] for key in list('xyz')]
    if surface == 'dots':
        ipv.scatter(x, y, z, marker='box', color=dot_color, size=dot_size)
    elif surface == 'full':
        ipv.plot_trisurf(x,
                         y,
                         z,
                         triangles=brain['surface']['tri'],
                         color=surface_color)

    # plot nodes
    if nodes:
        xyz = brain['nodes']['xyz']
        if node_colors:
            for label_idx, color in zip(np.unique(node_groups), node_colors):
                mask = node_groups == label_idx
                ipv.scatter(xyz[mask, 0],
                            xyz[mask, 1],
                            xyz[mask, 2],
                            marker='sphere',
                            color=color,
                            size=1.5)
        else:
            ipv.scatter(xyz[:, 0],
                        xyz[:, 1],
                        xyz[:, 2],
                        marker='sphere',
                        color=node_color,
                        size=1.5)

    # plot connections
    if network is not None:
        x, y, z = brain['nodes']['xyz'].T
        scaling = highest_cmap_color - lowest_cmap_color
        min_fibers_log = np.log(min_fibers)
        max_fibers_log = np.log(max_fibers)
        if hasattr(plt.cm, cmap):
            cmp = getattr(plt.cm, cmap)
        else:
            import seaborn as sns
            cmp = getattr(sns.cm, cmap)

        with fig.hold_sync():
            for ii in range(89):
                for jj in range(ii, 90):
                    if network[ii, jj] > min_fibers:
                        float_color = (min(
                            np.log((network[ii, jj] - min_fibers)) /
                            (max_fibers_log - min_fibers_log), 1.) * scaling +
                                       lowest_cmap_color)
                        line_color = cmp(float_color)
                        ipv.plot(x[[ii, jj]],
                                 y[[ii, jj]],
                                 z[[ii, jj]],
                                 color=line_color[:3])

    ipv.squarelim()
    ipv.style.use([background, 'minimal'])
    ipv.show()
    return fig
def add_optics(config):

    for key_opt in config['optics']:
        config_opt = config['optics'][key_opt]
        config_opt = xicsrt_config.config_to_numpy(config_opt)

        if True:
            w = config_opt['width'] / 2.0
            h = config_opt['height'] / 2.0
            cx = config_opt['xaxis']
            cy = np.cross(config_opt['xaxis'], config_opt['zaxis'])

            point0 = w * cx + h * cy + config_opt['origin']
            point1 = h * cy + config_opt['origin']
            point2 = -1 * w * cx + h * cy + config_opt['origin']

            point3 = w * cx + config_opt['origin']
            point4 = config_opt['origin']
            point5 = -1 * w * cx + config_opt['origin']

            point6 = w * cx - h * cy + config_opt['origin']
            point7 = -1 * h * cy + config_opt['origin']
            point8 = -1 * w * cx - h * cy + config_opt['origin']

            points = np.array([
                point0, point1, point2, point3, point4, point5, point6, point7,
                point8
            ])

            x = points[:, 0]
            y = points[:, 1]
            z = points[:, 2]

            # I am sure there is a way to automate this using a meshgrid,
            # but at the moment this is faster.
            triangles = ((4, 0, 2), (4, 2, 8), (4, 6, 8), (4, 6, 0))

            obj = ipv.plot_trisurf(x,
                                   y,
                                   z,
                                   triangles=triangles,
                                   color=[0.5, 0.5, 0.5, 0.5])
            obj.material.transparent = True

        if 'crystal' in str.lower(key_opt) and 'radius' in config_opt:

            # Initialize the configuration.
            # This merges the user config that we created
            # with the default config
            config = xicsrt_config.get_config(config)

            # The easiest way to do coordinate transformations is
            # to use the raytrace objects, since they already have
            # everything built in.  Of course we could do this
            # by just using some simple matrix multiplications,
            # but this way we can use existing code.
            #
            # We could just instantiate the objects directly as needed,
            # but since a dispatcher is already available in xicsrt that
            # does this for us, we might as well use it.  This is copied
            # from xicsrt_raytrace.raytrace_single.
            name = 'crystal'
            section = 'optics'
            optics = Dispatcher(config, section)
            optics.instantiate()
            optics.setup()
            optics.initialize()

            # Get the crystal object from the dispatcher.
            optic_obj = optics.get_object(name)

            crystal_center_ext = config_opt[
                'origin'] + config_opt['zaxis'] * config_opt['radius']
            crystal_center_loc = optic_obj.point_to_local(crystal_center_ext)

            x = np.array([crystal_center_ext[0]])
            y = np.array([crystal_center_ext[1]])
            z = np.array([crystal_center_ext[2]])
            ipv.scatter(x, y, z, color='black', marker="sphere")

            # Plot the crystal circle.
            num = 1000
            crystal_radius = config_opt['radius']
            coord_loc = np.zeros((num, 3))
            coord_loc[:, 0] = np.sin(np.linspace(
                0.0, np.pi * 2,
                num)) * config_opt['radius'] + crystal_center_loc[0]
            coord_loc[:, 1] = crystal_center_loc[1]
            coord_loc[:, 2] = np.cos(np.linspace(
                0.0, np.pi * 2,
                num)) * config_opt['radius'] + crystal_center_loc[2]
            coord_ext = optic_obj.point_to_external(coord_loc)
            x = coord_ext[:, 0]
            y = coord_ext[:, 1]
            z = coord_ext[:, 2]
            lines = np.zeros((num, 2), dtype=int)
            lines[:, 0] = np.arange(num)
            lines[:, 1] = np.roll(lines[:, 0], 1)
            obj = ipv.plot_trisurf(x,
                                   y,
                                   z,
                                   lines=lines,
                                   color=[0.0, 0.0, 0.0, 0.5])

            rowland_center_ext = config_opt[
                'origin'] + config_opt['zaxis'] * config_opt['radius'] / 2
            rowland_center_loc = optic_obj.point_to_local(rowland_center_ext)
            rowland_radius = crystal_radius / 2
            coord_loc = np.zeros((num, 3))
            coord_loc[:, 0] = np.sin(np.linspace(
                0.0, np.pi * 2, num)) * rowland_radius + rowland_center_loc[0]
            coord_loc[:, 1] = rowland_center_loc[1]
            coord_loc[:, 2] = np.cos(np.linspace(
                0.0, np.pi * 2, num)) * rowland_radius + rowland_center_loc[2]
            coord_ext = optic_obj.point_to_external(coord_loc)
            x = coord_ext[:, 0]
            y = coord_ext[:, 1]
            z = coord_ext[:, 2]
            lines = np.zeros((num, 2), dtype=int)
            lines[:, 0] = np.arange(num)
            lines[:, 1] = np.roll(lines[:, 0], 1)
            obj = ipv.plot_trisurf(x,
                                   y,
                                   z,
                                   lines=lines,
                                   color=[0.0, 0.0, 0.0, 0.5])