Esempio n. 1
0
    def make_voxel_graph(self, filename: str, max_score=500, c_map="inferno"):
        from graphviz import Graph
        from matplotlib import cm
        from matplotlib.colors import rgb_to_hsv

        # Make the graph and the list of all leaf voxels
        graph = Graph(comment='The voxel structure',
                      filename='Graphs/Graph_' + filename,
                      format='png')
        voxels = self.find_leaves(self.root)
        colormap = cm.get_cmap(c_map)

        for counter in range(len(voxels)):
            # Make a node for every voxel, with the size depending on the number of data points inside it
            size = len(voxels[counter].contents)
            graph.node('voxel' + str(counter),
                       label=None,
                       shape='point',
                       fixedsize='true',
                       width=str(0.05 * size))

        for counter in range(len(voxels)):
            # Draw for every node the edges corresponding to the neighbours
            nn = voxels[counter].neighbours

            # Limit the number of drawn neighbours
            if len(nn) > 3:
                top_nn = dict(sorted(nn.items(), key=lambda k: k[1][1])[:3])
            else:
                top_nn = nn

            # Change the drawing style and color depending on the type and score respectively
            for neighbour in top_nn:
                pointer = voxels.index(neighbour)
                ninfo = top_nn[neighbour]
                if ninfo[0] == 'face':
                    linestyle = 'solid'
                elif ninfo[0] == 'edge':
                    linestyle = 'dashed'
                else:
                    linestyle = 'dotted'

                if ninfo[1] > max_score:
                    print(f"Max score has been exceeded with {ninfo[1]}")
                    score = max_score
                else:
                    score = ninfo[1]
                norm = score / max_score
                color = rgb_to_hsv(colormap(norm)[0:3])
                graph.edge(
                    'voxel' + str(counter),
                    'voxel' + str(pointer),
                    style=linestyle,
                    color=f"{color[0]:.3f} {color[1]:.3f} {color[2]:.3f}")

        # Render the graph and save it
        u = graph.unflatten(stagger=5)
        u.render()