Esempio n. 1
0
def compute_figure(points, triangles, complex_type, scene):
    mesh = go.Mesh3d(
        x = points[:, 0], 
        y = points[:, 1], 
        z = points[:, 2], 
        i = triangles[:, 0], 
        j = triangles[:, 1], 
        k = triangles[:, 2], 
        name = complex_type + " Complex", 
        scene = scene
    )
    return mesh
def trisurf(x,
            y,
            z,
            simplices,
            show_colorbar,
            edges_color,
            scale,
            colormap=None,
            color_func=None,
            plot_edges=False,
            x_edge=None,
            y_edge=None,
            z_edge=None,
            facecolor=None):
    """
    Refer to FigureFactory.create_trisurf() for docstring
    """
    # numpy import check
    if not np:
        raise ImportError("FigureFactory._trisurf() requires "
                          "numpy imported.")
    points3D = np.vstack((x, y, z)).T
    simplices = np.atleast_2d(simplices)

    # vertices of the surface triangles
    tri_vertices = points3D[simplices]

    # Define colors for the triangle faces
    if color_func is None:
        # mean values of z-coordinates of triangle vertices
        mean_dists = tri_vertices[:, :, 2].mean(-1)
    elif isinstance(color_func, (list, np.ndarray)):
        # Pre-computed list / array of values to map onto color
        if len(color_func) != len(simplices):
            raise ValueError("If color_func is a list/array, it must "
                             "be the same length as simplices.")

        # convert all colors in color_func to rgb
        for index in range(len(color_func)):
            if isinstance(color_func[index], str):
                if '#' in color_func[index]:
                    foo = colors.hex_to_rgb(color_func[index])
                    color_func[index] = colors.label_rgb(foo)

            if isinstance(color_func[index], tuple):
                foo = colors.convert_to_RGB_255(color_func[index])
                color_func[index] = colors.label_rgb(foo)

        mean_dists = np.asarray(color_func)
    else:
        # apply user inputted function to calculate
        # custom coloring for triangle vertices
        mean_dists = []
        for triangle in tri_vertices:
            dists = []
            for vertex in triangle:
                dist = color_func(vertex[0], vertex[1], vertex[2])
                dists.append(dist)
            mean_dists.append(np.mean(dists))
        mean_dists = np.asarray(mean_dists)

    # Check if facecolors are already strings and can be skipped
    if isinstance(mean_dists[0], str):
        facecolor = mean_dists
    else:
        min_mean_dists = np.min(mean_dists)
        max_mean_dists = np.max(mean_dists)

        if facecolor is None:
            facecolor = []
        for index in range(len(mean_dists)):
            color = map_face2color(mean_dists[index], colormap, scale,
                                   min_mean_dists, max_mean_dists)
            facecolor.append(color)

    # Make sure facecolor is a list so output is consistent across Pythons
    facecolor = np.asarray(facecolor)
    ii, jj, kk = simplices.T

    triangles = graph_objs.Mesh3d(x=x,
                                  y=y,
                                  z=z,
                                  facecolor=facecolor,
                                  i=ii,
                                  j=jj,
                                  k=kk,
                                  name='')

    mean_dists_are_numbers = not isinstance(mean_dists[0], str)

    if mean_dists_are_numbers and show_colorbar is True:
        # make a colorscale from the colors
        colorscale = colors.make_colorscale(colormap, scale)
        colorscale = colors.convert_colorscale_to_rgb(colorscale)

        colorbar = graph_objs.Scatter3d(
            x=x[:1],
            y=y[:1],
            z=z[:1],
            mode='markers',
            marker=dict(size=0.1,
                        color=[min_mean_dists, max_mean_dists],
                        colorscale=colorscale,
                        showscale=True),
            hoverinfo='None',
            showlegend=False)

    # the triangle sides are not plotted
    if plot_edges is False:
        if mean_dists_are_numbers and show_colorbar is True:
            return graph_objs.Data([triangles, colorbar])
        else:
            return graph_objs.Data([triangles])

    # define the lists x_edge, y_edge and z_edge, of x, y, resp z
    # coordinates of edge end points for each triangle
    # None separates data corresponding to two consecutive triangles
    is_none = [ii is None for ii in [x_edge, y_edge, z_edge]]
    if any(is_none):
        if not all(is_none):
            raise ValueError("If any (x_edge, y_edge, z_edge) is None, "
                             "all must be None")
        else:
            x_edge = []
            y_edge = []
            z_edge = []

    # Pull indices we care about, then add a None column to separate tris
    ixs_triangles = [0, 1, 2, 0]
    pull_edges = tri_vertices[:, ixs_triangles, :]
    x_edge_pull = np.hstack(
        [pull_edges[:, :, 0],
         np.tile(None, [pull_edges.shape[0], 1])])
    y_edge_pull = np.hstack(
        [pull_edges[:, :, 1],
         np.tile(None, [pull_edges.shape[0], 1])])
    z_edge_pull = np.hstack(
        [pull_edges[:, :, 2],
         np.tile(None, [pull_edges.shape[0], 1])])

    # Now unravel the edges into a 1-d vector for plotting
    x_edge = np.hstack([x_edge, x_edge_pull.reshape([1, -1])[0]])
    y_edge = np.hstack([y_edge, y_edge_pull.reshape([1, -1])[0]])
    z_edge = np.hstack([z_edge, z_edge_pull.reshape([1, -1])[0]])

    if not (len(x_edge) == len(y_edge) == len(z_edge)):
        raise exceptions.PlotlyError("The lengths of x_edge, y_edge and "
                                     "z_edge are not the same.")

    # define the lines for plotting
    lines = graph_objs.Scatter3d(x=x_edge,
                                 y=y_edge,
                                 z=z_edge,
                                 mode='lines',
                                 line=graph_objs.Line(color=edges_color,
                                                      width=1.5),
                                 showlegend=False)

    if mean_dists_are_numbers and show_colorbar is True:
        return graph_objs.Data([triangles, lines, colorbar])
    else:
        return graph_objs.Data([triangles, lines])