def addVector(start, v):
        global color_index

        color = colors[color_index]
        color_index = (color_index + 1) % len(colors)

        end = start + v
        trace = go.Scatter3d(x=[start[0], end[0], None],
                             y=[start[1], end[1], None],
                             z=[start[2], end[2], None],
                             mode='lines',
                             name=str(v),
                             line=dict(color=color, width=4))
        norm = np.sqrt(np.sum(v * v))
        n = v if norm == 0 else v / norm
        n = 1.5 * n
        c_end = end - 0.37 * n
        cone = go.Cone(x=[c_end[0]],
                       y=[c_end[1]],
                       z=[c_end[2]],
                       u=[n[0]],
                       v=[n[1]],
                       w=[n[2]],
                       name=str(v),
                       colorscale=[[0, color], [1, color]],
                       hoverinfo="none",
                       showscale=False)

        data.append(trace)
        data.append(cone)
Exemplo n.º 2
0
def get_3D_quiver_trace(points, directions, color='#bd1540', name=''):
    assert points.shape[
        1] == 3, "3d cone plot input points are not correctely shaped "
    assert len(points.shape
               ) == 2, "3d cone plot input points are not correctely shaped "
    assert directions.shape[
        1] == 3, "3d cone plot input directions are not correctely shaped "
    assert len(
        directions.shape
    ) == 2, "3d cone plot input directions are not correctely shaped "

    trace = go.Cone(name=name,
                    x=points[:, 0].cpu(),
                    y=points[:, 1].cpu(),
                    z=points[:, 2].cpu(),
                    u=directions[:, 0].cpu(),
                    v=directions[:, 1].cpu(),
                    w=directions[:, 2].cpu(),
                    sizemode='absolute',
                    sizeref=0.125,
                    showscale=False,
                    colorscale=[[0, color], [1, color]],
                    anchor="tail")

    return trace
Exemplo n.º 3
0
def draw_vector_R3(h,
                   t=np.zeros((3, )),
                   color='rgb(0, 0, 0)',
                   name='',
                   arrow_size=0.,
                   showlegend=False,
                   textposition=None):

    q = np.linalg.norm(h - t)
    f = lambda q: np.exp(np.power(q / 2.5, 2.5 / 9))

    if arrow_size == 0.:
        a = .99 - np.exp(-f(q))
        arrow_size = .6 * (a**(1.7))

    g = lambda q: 1. - np.exp(-0.85 * q)
    q = .99 - np.exp(-g(q) * f(q))

    x, y, z = h
    u, v, w = h - t
    cone = go.Cone(x=[x],
                   y=[y],
                   z=[z],
                   u=[u],
                   v=[v],
                   w=[w],
                   anchor="tip",
                   sizemode="absolute",
                   sizeref=arrow_size,
                   name=name,
                   hoverinfo='x+y+z+name',
                   hoverlabel=dict(bgcolor=color),
                   colorscale=[[0, color], [0.5, color], [1.0, color]],
                   showscale=False)

    lx = [t[0], t[0] + q * (h[0] - t[0])]
    ly = [t[1], t[1] + q * (h[1] - t[1])]
    lz = [t[2], t[2] + q * (h[2] - t[2])]
    l = go.Scatter3d(
        x=lx,
        y=ly,
        z=lz,
        showlegend=showlegend,
        text=['', name],
        textfont=dict(color=color),
        hoverinfo='none',
        line=dict(
            color=color,
            #            color='rgb(0, 255, 0)',
            width=9,
        ),
        mode='lines, text')

    mx = np.max(np.abs([h, t]))

    data = [l, cone]
    return data, mx
Exemplo n.º 4
0
def vector_plot(result, titles, verbose=False, **kwargs):
    variable = titles['variable']
    val0 = list(result.values())[0]

    if (result[variable].shape == val0.shape) & (val0.shape[1] == 2):
        if verbose:
            print('\t 2-d output', result[variable].shape)
        u = result[variable][:, 0]
        v = result[variable][:, 1]
        x = val0[:, 0]
        y = val0[:, 1]

        trace = ff.create_quiver(
            x,
            y,
            u,
            v,
            # scale=.25,
            # arrow_scale=.4,
            name='quiver',
            line=dict(width=1))['data'][0]  # extracts quiver trace

        layout = go.Layout(title=titles['title'],
                           xaxis=dict(title='x'),
                           yaxis=dict(title='y'))
        chart_type = '2d-vector'

    elif (result[variable].shape == val0.shape) & (val0.shape[1] == 3):
        if verbose:
            print('\t 3-d output', result[variable].shape)
        u = result[variable][:, 0].tolist()
        v = result[variable][:, 1].tolist()
        w = result[variable][:, 2].tolist()
        x = val0[:, 0].tolist()
        y = val0[:, 1].tolist()
        z = val0[:, 2].tolist()
        trace = go.Cone(x=x, y=y, z=z, u=u, v=v, w=w)

        layout = go.Layout(title=titles['title'],
                           scene=dict(
                               xaxis=dict(title='x'),
                               yaxis=dict(title='y'),
                               zaxis=dict(title='z'),
                           ))
        chart_type = '3d-vector'
    else:
        raise NotImplementedError('plot type not supported yet')

    return [trace], chart_type, layout
Exemplo n.º 5
0
    def draw(self):
        from mlreco.visualization import plotly_layout3d
        from mlreco.visualization.voxels import scatter_voxels, scatter_label
        import plotly.plotly as py
        import plotly.graph_objs as go
        from plotly.offline import init_notebook_mode, iplot
        init_notebook_mode(connected=False)

        # Create labels for the voxels
        # Use a different color for each cluster
        labels = np.full(len(self.output['energy'][:,-1]), -1)
        for i, s in enumerate(self.output['showers']):
            labels[s.voxels] = i

        # Draw voxels with cluster labels
        voxels = self.output['energy'][:,:3]
        graph_voxels = scatter_label(voxels, labels, 2)[0]
        graph_voxels.name = 'Shower ID'
        graph_data = [graph_voxels]

        if len(self.output['showers']):
            # Add EM primary points
            points = np.array([s.start for s in self.output['showers']])
            graph_start = scatter_voxels(points)[0]
            graph_start.name = 'Shower starts'
            graph_data.append(graph_start)
            
            # Add EM primary directions
            dirs = np.array([s.direction for s in self.output['showers']])
            arrows = go.Cone(x=points[:,0], y=points[:,1], z=points[:,2], 
                             u=dirs[:,0], v=dirs[:,1], w=dirs[:,2],
                             sizemode='absolute', sizeref=0.25, anchor='tail',
                             showscale=False, opacity=0.4)
            graph_data.append(arrows)

            # Add a vertex if matches, join vertex to start points
            for i, m in enumerate(self.output['matches']):
                v = self.output['vertices'][i]
                s1, s2 = self.output['showers'][m[0]].start, self.output['showers'][m[1]].start
                points = [v, s1, v, s2]
                line = scatter_voxels(np.array(points))[0]
                line.name = 'Pi0 Decay'
                line.mode = 'lines,markers'
                graph_data.append(line)

        # Draw
        iplot(go.Figure(data=graph_data,layout=plotly_layout3d()))
Exemplo n.º 6
0
def vector_plot(result, titles, verbose = False, **kwargs):
    variable = titles['variable']
    val0 = list(result.values())[0]

    # check if this is a 2d vector plot: input and output should have shape 2d
    if (result[variable].shape == val0.shape) & (val0.shape[1] == 2):
        if verbose:
            print('\t 2-d output', result[variable].shape)
        u = result[variable][:, 0]
        v = result[variable][:, 1]
        x = val0[:, 0]
        y = val0[:, 1]

        # plotly's quiver plot has its own defaults
        quiver_defaults = get_defaults(ff.create_quiver)
        for k, v_ in kwargs.items():
            if k in quiver_defaults:
                quiver_defaults[k] = v_
        if verbose:
            print(quiver_defaults)
        try:
            trace = ff.create_quiver(
                x, y, u, v,
                name='quiver',
                line=dict(width=1),
                **quiver_defaults)['data'][0] # extracts quiver trace
        except:
            print('problem with quiver, u,v,x,y shapes:')
            for v_ in [u, v, x, y]:
                print(v_.shape)
            raise

        layout = go.Layout(title=titles['title'],
                           xaxis=dict(title='x'),
                           yaxis=dict(title='y'))
        chart_type = '2d-vector'

    # check if this is a 3d vector plot: input and output should have shape 3d
    elif (result[variable].shape == val0.shape) & (val0.shape[1] == 3):
        if verbose:
            print('\t 3-d output', result[variable].shape, val0.shape)
            print('\t 3d vector plot')
        if type(result[variable]) == pd.DataFrame:
            u = result[variable].values[:, 0].tolist()
            v = result[variable].values[:, 1].tolist()
            w = result[variable].values[:, 2].tolist()
        else:
            u = result[variable][:, 0].tolist()
            v = result[variable][:, 1].tolist()
            w = result[variable][:, 2].tolist()
        if type(val0) == pd.DataFrame:
            x = val0.values[:, 0].tolist()
            y = val0.values[:, 1].tolist()
            z = val0.values[:, 2].tolist()
        else:
            x = val0[:, 0].tolist()
            y = val0[:, 1].tolist()
            z = val0[:, 2].tolist()

        # normalize each vector to get the length
        norms = np.linalg.norm(result[variable], axis=1)
        trace = go.Cone(
            x=x, y=y, z=z, u=u, v=v, w=w,
            hoverinfo='x+y+z+u+v+w+norm',
            colorscale='Reds',
            cmin=0, cmax=norms.max(),
            )

        layout = go.Layout(
            title=titles['title'],
            scene=dict(
                xaxis=dict(title='x'),
                yaxis=dict(title='y'),
                zaxis=dict(title='z'),
                ))
        chart_type = '3d-vector'
    else:
        raise NotImplementedError('plot type not supported yet')

    return [trace], chart_type, layout
Exemplo n.º 7
0
def display_scatterplot_3D(model,
                           user_input=None,
                           words=None,
                           label=None,
                           color_map=None,
                           annotation='On',
                           dim_red='PCA',
                           perplexity=0,
                           learning_rate=0,
                           iteration=0,
                           topn=0,
                           sample=10):

    if words == None:
        if sample > 0:
            words = np.random.choice(list(model.wv.vocab.keys()), sample)
        else:
            words = np.random.choice(list(model.wv.vocab.keys()), 10)

    word_vectors = np.array([model.wv.get_vector(w) for w in words])

    if dim_red == 'PCA':
        three_dim = PCA(random_state=0).fit_transform(word_vectors)[:, :3]
    else:
        three_dim = TSNE(n_components=3,
                         random_state=0,
                         perplexity=perplexity,
                         learning_rate=learning_rate,
                         n_iter=iteration).fit_transform(word_vectors)[:, :3]

    color = 'blue'
    quiver = go.Cone(x=[0, 0, 0],
                     y=[0, 0, 0],
                     z=[0, 0, 0],
                     u=[1.5, 0, 0],
                     v=[0, 1.5, 0],
                     w=[0, 0, 1.5],
                     anchor="tail",
                     colorscale=[[0, color], [1, color]],
                     showscale=False)

    data = [quiver]

    count = 0
    for i in range(len(user_input)):

        trace = go.Scatter3d(x=three_dim[count:count + topn, 0],
                             y=three_dim[count:count + topn, 1],
                             z=three_dim[count:count + topn, 2],
                             text=words[count:count +
                                        topn] if annotation == 'On' else '',
                             name=user_input[i],
                             textposition="top center",
                             textfont_size=15,
                             mode='markers+text',
                             marker={
                                 'size': 10,
                                 'opacity': 0.8,
                                 'color': 2
                             })

        data.append(trace)
        count = count + topn

    trace_input = go.Scatter3d(x=three_dim[count:, 0],
                               y=three_dim[count:, 1],
                               z=three_dim[count:, 2],
                               text=words[count:],
                               name='input words',
                               textposition="top center",
                               textfont_size=15,
                               mode='markers+text',
                               marker={
                                   'size': 10,
                                   'opacity': 1,
                                   'color': 'black'
                               })

    data.append(trace_input)

    # Configure the layout.
    layout = go.Layout(margin={
        'l': 0,
        'r': 0,
        'b': 0,
        't': 0
    },
                       showlegend=True,
                       legend=dict(x=1,
                                   y=0.5,
                                   font=dict(family="Courier New",
                                             size=15,
                                             color="black")),
                       font=dict(family=" Courier New ", size=15),
                       autosize=True,
                       width=1000,
                       height=1000)

    plot_figure = go.Figure(data=data, layout=layout)

    st.plotly_chart(plot_figure)
Exemplo n.º 8
0
def get_graphs(filename, entry, modifiers):
    info = get_info_for_entry(filename, entry)

    fig = make_subplots()

    jet_pt = info["jet_pt"]
    jet_eta = info["jet_eta"]
    jet_phi = info["jet_phi"]
    jet_mass = info["jet_mass"]
    njet = len(jet_pt)
    vx, vy, vz = [], [], []
    vu, vv, vw = [], [], []
    hovertexts = []
    for i in range(njet):
        hovertexts.append(f"<b>Jet</b><br>p<sub>T</sub> = {jet_pt[i]:.1f}<br>η = {jet_eta[i]:.2f}<br>φ = {jet_phi[i]:.2f}<br>mass = {jet_mass[i]:.1f}")
        vx.append(0)
        vy.append(0)
        vz.append(0)
        x, y, z = ptetaphi_to_xyz(jet_pt[i], jet_eta[i], jet_phi[i], norm=True)
        vu.append(y)
        vv.append(z)
        vw.append(z)
    fig.add_trace(
        go.Cone(
            x=vx,
            y=vz,
            z=vy,  # note the flip
            u=vu,
            v=vw,
            w=vv,  # note the flip
            sizemode="absolute",
            anchor="tip",
            colorscale=[[0, "red"], [1, "red"]],
            name=f"Jets ({njet})",
            showlegend=True,
            showscale=False,
            opacity=0.3,
            hoverinfo="text",
            hovertext=hovertexts,
        ),
    )

    electron_pt = info["electron_pt"]
    electron_eta = info["electron_eta"]
    electron_phi = info["electron_phi"]
    electron_charge = info["electron_charge"]
    nelectron = len(electron_pt)
    vx, vy, vz = [], [], []
    vu, vv, vw = [], [], []
    hovertexts = []
    for i in range(nelectron):
        hovertexts.append(f"<b>Electron</b><br>p<sub>T</sub> = {electron_pt[i]:.1f}<br>η = {electron_eta[i]:.2f}<br>φ = {electron_phi[i]:.2f}<br>charge = {electron_charge[i]:+}")
        vx.append(0)
        vy.append(0)
        vz.append(0)
        x, y, z = ptetaphi_to_xyz(electron_pt[i], electron_eta[i], electron_phi[i], norm=True)
        vu.append(y)
        vv.append(z)
        vw.append(z)

    fig.add_trace(
        go.Cone(
            x=vx,
            y=vz,
            z=vy,  # note the flip
            u=vu,
            v=vw,
            w=vv,  # note the flip
            sizemode="absolute",
            anchor="tip",
            colorscale=[[0, "blue"], [1, "blue"]],
            name=f"Electrons ({nelectron})",
            showlegend=True,
            showscale=False,
            opacity=0.3,
            hoverinfo="text",
            hovertext=hovertexts,
        ),
    )


    muon_pt = info["muon_pt"]
    muon_eta = info["muon_eta"]
    muon_phi = info["muon_phi"]
    muon_charge = info["muon_charge"]
    nmuon = len(muon_pt)
    # return to 0 each time
    vx, vy, vz = [], [], []
    hovertexts = []
    for i in range(nmuon):
        hovertexts.append("")
        vx.append(0)
        vy.append(0)
        vz.append(0)
        hovertexts.append(f"<b>Muon</b><br>p<sub>T</sub> = {muon_pt[i]:.1f}<br>η = {muon_eta[i]:.2f}<br>φ = {muon_phi[i]:.2f}<br>charge = {muon_charge[i]:+}")
        x, y, z = ptetaphi_to_xyz(muon_pt[i], muon_eta[i], muon_phi[i], norm=True)
        vx.append(x)
        vy.append(y)
        vz.append(z)
    fig.add_trace(
        go.Scatter3d(
            x=vx,
            y=vz,
            z=vy,  # note the flip
            marker=dict(size=0.001),
            line=dict(color="red", width=4),
            name=f"Muons ({nmuon})",
            mode="lines+markers",
            hoverinfo="text",
            hovertext=hovertexts,
        )
    )

    met_pt = info["met_pt"]
    met_phi = info["met_phi"]
    x, y, z = ptetaphi_to_xyz(met_pt, 0., met_phi, norm=True)
    vx = [0, x]
    vy = [0, y]
    vz = [0, z]
    fig.add_trace(
        go.Scatter3d(
            x=vx,
            y=vz,
            z=vy,  # note the flip
            marker=dict(size=0.001),
            line=dict(color="black", width=4),
            name="MET",
            mode="lines+markers",
            hoverinfo="name+text",
            hovertemplate=f"p<sub>T</sub> = {met_pt:.1f} GeV<br>φ = {met_phi:.2f}"
        )
    )

    vx, vy, vz = cylinder(1, 4, a=-2, nt=20, nv=2)
    fig.add_trace(
        go.Surface(
            x=vx,
            y=vz,
            z=vy,  # note the flip
            colorscale=[[0, "gray"], [1, "gray"]],
            opacity=0.1,
            showscale=False,
            hoverinfo="none",
            name="Dumb cylinder",
            showlegend=True,
            visible="legendonly",
        )
    )

    sf = 0.5
    fig.update_layout(
        height=600,
        width=800,
        template="plotly",
        scene=dict(
            aspectratio=dict(x=sf * 1, y=sf * 2, z=sf * 1),
            xaxis=dict(
                tickvals= [-1,+1],
                title="x",
                range=[-1, 1],
                showspikes=False,
            ),
            yaxis=dict(
                tickvals= [-1,+1],
                title="z",
                range=[-2, 2],
                showspikes=False,
            ),
            zaxis=dict(
                tickvals= [-1,+1],
                title="y",
                range=[-1, 1],
                showspikes=False,
            ),
        ),
        margin=dict(r=0, b=0, l=0, t=0),
        legend=dict(yanchor="top", y=0.99, xanchor="left", x=0.01),
    )

    g_plot = dcc.Graph(figure=fig, id='g_plot')
    return [g_plot]
Exemplo n.º 9
0
    def draw(self, **kargs):
        import plotly
        from mlreco.visualization.points import scatter_points
        import plotly.graph_objs as go
        from plotly.offline import iplot

        graph_data = []
        # Draw voxels with cluster labels
        energy = self.output['energy']
        shower_mask = self.output['shower_mask']
        graph_data += scatter_points(energy,
                                     markersize=2,
                                     color=energy[:, -1],
                                     colorscale='Inferno')
        graph_data[-1].name = 'Energy'

        colors = plotly.colors.qualitative.Light24
        for i, s in enumerate(self.output['showers']):
            points = energy[shower_mask][s.voxels]
            color = colors[i % (len(colors))]
            graph_data += scatter_points(points, markersize=2, color=color)
            graph_data[-1].name = 'Shower %d (id=%d)' % (i, s.pid)

        if len(self.output['showers']):

            # Add EM primary points
            points = np.array([s.start for s in self.output['showers']])
            graph_data += scatter_points(points)
            graph_data[-1].name = 'Shower Starts'

            # Add EM primary directions
            dirs = np.array([s.direction for s in self.output['showers']])
            cone_start = points[:, :3]
            arrows = go.Cone(x=cone_start[:, 0],
                             y=cone_start[:, 1],
                             z=cone_start[:, 2],
                             u=-dirs[:, 0],
                             v=-dirs[:, 1],
                             w=-dirs[:, 2],
                             sizemode='absolute',
                             sizeref=1.0,
                             anchor='tip',
                             showscale=False,
                             opacity=0.4)
            graph_data.append(arrows)

            # Add a vertex if matches, join vertex to start points
            if 'matches' in self.output:
                for i, match in enumerate(self.output['matches']):
                    v = self.output['vertices'][i]
                    idx1, idx2 = match
                    s1, s2 = self.output['showers'][idx1].start, self.output[
                        'showers'][idx2].start
                    points = [v, s1, v, s2]
                    graph_data += scatter_points(np.array(points), color='red')
                    graph_data[
                        -1].name = 'Pi0 (%.2f MeV)' % self.output['masses'][i]
                    graph_data[-1].mode = 'lines,markers'

        # Draw
        #go.Figure(data=graph_data,layout=self.layout(**kargs))
        from mlreco.visualization import plotly_layout3d
        fig = go.Figure(data=graph_data, layout=plotly_layout3d())
        camera = dict(up=dict(x=0, y=0, z=0),
                      center=dict(x=0, y=0, z=-0.3),
                      eye=dict(x=0.4, y=0.4, z=0.4))
        fig.update_layout(scene_camera=camera, showlegend=False)
        iplot(fig)
Exemplo n.º 10
0
                zs.append(z)

                us.append(tom[x][y][z][0])
                vs.append(tom[x][y][z][1])
                ws.append(tom[x][y][z][2])
                i += 1
                print(i)
                #if i >= 500:
                #    break
            #if i >= 500:
            #    break
        #if i >= 500:
        #    break

    #fig = px.scatter_3d(x=xs, y=ys, z=zs, color=np.array([1 for i in range(len(xs))]), size=[0.5 for item in xs], range_x=[0,144], range_y=[0,144], range_z=[0,144])
    fig = go.Figure(data=go.Cone(x=xs, y=ys, z=zs, u=us, v=vs, w=ws))
    #fig = px.scatter_3d(x=xs, y=ys, z=zs, color=np.array(["rgb(" + str(abs(us[i])) + "," + str(abs(vs[i])) + "," + str(abs(ws[i])) + ")" for i in range(len(xs))]), size=[0.1 for item in xs], range_x=[0,144], range_y=[0,144], range_z=[0,144])
    fig.update_layout(
        scene_aspectmode='cube',
        scene=dict(xaxis=dict(range=[0, 144]),
                   yaxis=dict(range=[0, 144]),
                   zaxis=dict(range=[0, 144])),
        scene_camera=camera,
    )
    fig.show()
    """
    print(len(xs), len(ys), len(zs))
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.set_xlim([0, 144])
    ax.set_ylim([0, 144])
Exemplo n.º 11
0
def network_topology(voxels, clusters, primaries, edges, mode='sphere'):
    """
    Network 3D topological representation
    - voxels is a list of voxel coordinates (Nx3-matrix)
    - clusters is an array of clusters, each defined as an array of voxel ids
    - primaries is a list of the primary cluster ids
    - edges is list of pairs of cluster ids arranged in two vectors (2xM-vector)
    """
    # Define the arrays of node positions (barycenter of voxels in the cluster)
    pos = np.array([voxels[c].cpu().numpy().mean(0) for c in clusters])

    # Define the node features (label, color)
    n = len(clusters)
    node_labels = [
        '%d (%0.1f, %0.1f, %0.1f)' % (i, pos[i, 0], pos[i, 1], pos[i, 2])
        for i in range(n)
    ]

    node_colors = [
        '#ff7f0e' if i in primaries else '#1f77b4' for i in range(n)
    ]

    # Assert if there is edges to draw
    draw_edges = bool(edges.shape[1]) if len(edges) == 2 else False

    # Define the nodes and their connections
    graph_data = []
    edge_vertices = []
    if mode == 'sphere':
        # Define the node size as a linear function of the amount of voxels in the cluster
        sizes = np.array([len(c) for c in clusters])
        node_sizes = sizes * 50. / sizes.max()

        # Define the nodes as sphere of radius proportional to the log of the cluster voxel content
        graph_data.append(
            go.Scatter3d(x=pos[:, 0],
                         y=pos[:, 1],
                         z=pos[:, 2],
                         name='clusters',
                         mode='markers',
                         marker=dict(symbol='circle',
                                     size=node_sizes,
                                     color=node_colors,
                                     colorscale='Viridis',
                                     line=dict(color='rgb(50,50,50)',
                                               width=0.5)),
                         text=node_labels,
                         hoverinfo='text'))

        # Define the edges center to center
        if draw_edges:
            edge_vertices = np.concatenate(
                [[pos[i], pos[j], [None, None, None]]
                 for i, j in zip(edges[0], edges[1])])

    elif mode == 'cone':
        # Evaluate the cone parameters
        from sklearn.decomposition import PCA
        import numpy.linalg as LA
        pca = PCA()
        axes, spos, epos = np.empty((0, 3)), np.empty((0, 3)), np.empty((0, 3))
        curv = lambda vox, pid, norm :\
            np.sum([np.abs(np.dot((v-vox[pid])/LA.norm(v-vox[pid]), norm)) for i, v in enumerate(vox) if i != pid])
        for c in clusters:
            # Get the voxels corresponding to the cluster
            vox = voxels[c].numpy()

            # Get the mean and the principal axis from the PCA
            pca.fit(vox)
            axis = np.array([pca.components_[0][i] for i in range(3)])

            # Order the point along the principal axis, get the end points
            pa_vals = np.dot(vox, axis)
            pids = np.argmax(pa_vals), np.argmin(pa_vals)

            # Identify the starting point as the point with the largest curvature
            curvs = [curv(vox, pid, axis) for pid in pids]
            start_id, end_id = pids[np.argmax(curvs)], pids[np.argmin(curvs)]
            spos = np.concatenate((spos, [vox[start_id]]))
            epos = np.concatenate((epos, [vox[end_id]]))

            # Get the full length of the principal axis
            pa_dist = pa_vals[start_id] - pa_vals[end_id]

            # Append the cone parameters
            axes = np.concatenate((axes, [2. * pa_dist * axis]))

        # Compute plotly's internal vector scale to undo it...
        vector_scale = np.inf
        for i, p in enumerate(spos):
            u = axes[i]
            if i > 0:
                vector_scale = min(
                    vector_scale,
                    2 * LA.norm(p2 - p) / (LA.norm(u2) + LA.norm(u)))
            p2 = p
            u2 = u

        # Add a graph with a cone per cluster
        graph_data.append(
            go.Cone(x=spos[:, 0],
                    y=spos[:, 1],
                    z=spos[:, 2],
                    u=axes[:, 0],
                    v=axes[:, 1],
                    w=axes[:, 2],
                    name='clusters',
                    opacity=.5,
                    sizeref=.5 / vector_scale,
                    showscale=False,
                    anchor='tip'))

        # Add a graph with the starting points
        graph_data.append(
            go.Scatter3d(x=spos[:, 0],
                         y=spos[:, 1],
                         z=spos[:, 2],
                         name='nodes',
                         mode='markers',
                         marker=dict(symbol='circle',
                                     color=node_colors,
                                     size=5,
                                     colorscale='Viridis'),
                         text=node_labels,
                         hoverinfo='text'))

        # Join end points of primary cones to starting points of secondary cones
        for e in edges:
            edge_vertices = np.concatenate(
                [[epos[i], spos[j], [None, None, None]]
                 for i, j in zip(edges[0], edges[1])])

    elif mode == 'hull':
        # For each cluster, add the convex hull of all its voxels
        graph_data += [
            go.Mesh3d(alphahull=10.0,
                      name='',
                      x=voxels[c][:, 0],
                      y=voxels[c][:, 1],
                      z=voxels[c][:, 2],
                      color=node_colors[i],
                      opacity=0.3,
                      text=node_labels[i],
                      hoverinfo='text') for i, c in enumerate(clusters)
        ]

        # Define the edges closest pixel to closest pixel
        import scipy as sp
        edge_vertices = []
        for i, j in zip(edges[0], edges[1]):
            vi, vj = voxels[clusters[i]], voxels[clusters[j]]
            d12 = sp.spatial.distance.cdist(vi, vj, 'euclidean')
            i1, i2 = np.unravel_index(np.argmin(d12), d12.shape)
            edge_vertices.append([
                vi[i1].cpu().numpy(), vj[i2].cpu().numpy(), [None, None, None]
            ])

        if draw_edges:
            edge_vertices = np.concatenate(edge_vertices)

    elif mode == 'scatter':
        # Simply draw all the voxels of each cluster, using primary as color
        cids = np.full(len(voxels), -1)
        for i, c in enumerate(clusters):
            cids[c] = i

        mask = np.where(cids != -1)[0]
        colors = [node_colors[i] for i in cids[mask]]
        labels = [node_labels[i] for i in cids[mask]]

        graph_data = [
            go.Scatter3d(x=voxels[mask][:, 0],
                         y=voxels[mask][:, 1],
                         z=voxels[mask][:, 2],
                         mode='markers',
                         marker=dict(symbol='circle', color=colors, size=1),
                         text=labels,
                         hoverinfo='text')
        ]

        # Define the edges closest pixel to closest pixel
        if draw_edges:
            import scipy as sp
            edge_vertices = []
            for i, j in zip(edges[0], edges[1]):
                vi, vj = voxels[clusters[i]], voxels[clusters[j]]
                d12 = sp.spatial.distance.cdist(vi, vj, 'euclidean')
                i1, i2 = np.unravel_index(np.argmin(d12), d12.shape)
                edge_vertices.append([
                    vi[i1].cpu().numpy(), vj[i2].cpu().numpy(),
                    [None, None, None]
                ])

            edge_vertices = np.concatenate(edge_vertices)

    else:
        raise ValueError("Network topology mode not supported")

    # Initialize a graph that contains the edges
    if draw_edges:
        graph_data.append(
            go.Scatter3d(x=edge_vertices[:, 0],
                         y=edge_vertices[:, 1],
                         z=edge_vertices[:, 2],
                         mode='lines',
                         name='edges',
                         line=dict(color='rgba(50, 50, 50, 0.5)', width=5),
                         hoverinfo='none'))

    # Return
    return graph_data
Exemplo n.º 12
0
                     y=[
                         dataset_dict['data'][i, 1],
                         dataset_dict['data'][i, 1] + line_length * t1[1]
                     ],
                     z=[
                         dataset_dict['data'][i, 2],
                         dataset_dict['data'][i, 2] + line_length * t1[2]
                     ],
                     mode='lines',
                     line=dict(width=line_width, color='red')))
    # drawing the arrowhead (is there an easier way?):
    pd.append(
        go.Cone(x=[dataset_dict['data'][i, 0] + line_length * t1[0]],
                y=[dataset_dict['data'][i, 1] + line_length * t1[1]],
                z=[dataset_dict['data'][i, 2] + line_length * t1[2]],
                u=[arrow_cone_length * t1[0]],
                v=[arrow_cone_length * t1[1]],
                w=[arrow_cone_length * t1[2]],
                colorscale='Reds'))

    # plot the tangent space eigenvector #2:
    pd.append(
        go.Scatter3d(x=[
            dataset_dict['data'][i, 0],
            dataset_dict['data'][i, 0] + line_length * t2[0]
        ],
                     y=[
                         dataset_dict['data'][i, 1],
                         dataset_dict['data'][i, 1] + line_length * t2[1]
                     ],
                     z=[
Exemplo n.º 13
0
    def cones(self,
              x=None, y=None, z=None, u=None, v=None, w=None, conesize=40,
              width=700, height=700, res=50, grid=True, pane_fill=None, prune=None,
              x_slice=True, x_center=None, x_scale=1, x_lim=None,
              y_slice=True, y_center=-3.5, y_scale=1, y_lim=None,
              z_slice=True, z_center=None, z_scale=1, z_lim=None,
              norm=None, cb_labelpad=10, cb_nticks=10, cb_x=None, cb_y=None,
              cb_title=None, cb_length=0.75, cb_outlinecolor=None, cb_outlinewidth=1, cb_tickfontsize=10,
              plot_title='Airstream', title_bold=True, title_size=20, title_pad=5, title_y=0.85,
              x_label='x', xaxis_bold=False, xaxis_labelpad=5, xlabel_rotation=None, x_tick_number=10,
              y_label='y', yaxis_bold=False, yaxis_labelpad=5, ylabel_rotation=None, y_tick_number=10,
              z_label='z', zaxis_bold=False, zaxis_labelpad=5, zlabel_rotation=None, z_tick_number=10,
              axis_label_size=20, tick_color=None, tick_label_size=12, tick_label_pad=5,
              xtick_rotation=None, ytick_rotation=None, ztick_rotation=None,
              floating_text=None,
              filename=None):

        # Colorbar parameters
        self.cb_outlinecolor = cb_outlinecolor if cb_outlinecolor is not None else self.color2
        self.cb_outlinewidth = cb_outlinewidth
        self.cb_length = cb_length
        self.cb_title = cb_title
        self.cb_x = cb_x
        self.cb_y = cb_y
        self.cb_xpad = cb_labelpad
        self.cb_nticks = cb_nticks
        self.cb_tickfontsize = cb_tickfontsize

        # Mock plot
        if isinstance(x, type(None)) and isinstance(y, type(None)) and isinstance(z, type(None)) \
                and isinstance(u, type(None)) and isinstance(v, type(None)) and isinstance(w, type(None)):
            df = pd.read_csv(
                r"C:\Users\xXY4n\AE BSc\AE Year 2\Aerodynamics project\Data Analysis\data\velocity_planes_of_interest\x=-10\x=-10_projected\-10_-8_7.csv",
                index_col=0)
            df.columns = list('--xyzuvw')
            x, y, z, u, v, w = df['x'], df['y'], df['z'], df['u'], df['v'], df['w']
            x_scale = (abs(x.max())+abs(x.min()))/max(abs(x.max())+abs(x.min()), abs(y.max())+abs(y.min()), abs(z.max())+abs(z.min()))
            y_scale = (abs(y.max())+abs(y.min()))/max(abs(x.max())+abs(x.min()), abs(y.max())+abs(y.min()), abs(z.max())+abs(z.min()))
            z_scale = (abs(z.max())+abs(z.min()))/max(abs(x.max())+abs(x.min()), abs(y.max())+abs(y.min()), abs(z.max())+abs(z.min()))

        # Individual axis setup
        axis = dict(showbackground=True,
                    backgroundcolor=pane_fill,
                    showgrid=grid,
                    gridcolor=self.color2,
                    zerolinecolor=self.color2,
                    tickfont={'family': self.font,
                              'size': tick_label_size,
                              'color': tick_color},
                    titlefont={'family': self.font,
                               'size': axis_label_size},
                    )

        # Layout
        layout = go.Layout(
            width=width,
            height=height,
            scene=dict(xaxis=dict(axis, range=x_lim, tickangle=xtick_rotation, nticks=x_tick_number, title='<b>'+x_label+'</b>' if xaxis_bold is True else x_label),
                       yaxis=dict(axis, range=y_lim, tickangle=ytick_rotation, nticks=y_tick_number, title='<b>'+y_label+'</b>' if yaxis_bold is True else y_label),
                       zaxis=dict(axis, range=z_lim, tickangle=ztick_rotation, nticks=z_tick_number, title='<b>'+z_label+'</b>' if zaxis_bold is True else z_label),
                       aspectratio=dict(x=x_scale, y=y_scale, z=z_scale)
                       ),
            template=self.template
        )

        # Plot
        fig = go.Figure(data=go.Cone(x=x,
                                     y=y,
                                     z=z,
                                     u=u,
                                     v=v,
                                     w=w,
                                     colorscale=self.cmap,
                                     sizemode='absolute',
                                     sizeref=conesize,
                                     colorbar=dict(len=self.cb_length,
                                                   x=self.cb_x,
                                                   xpad=self.cb_xpad,
                                                   y=self.cb_y,
                                                   outlinecolor=self.cb_outlinecolor,
                                                   outlinewidth=self.cb_outlinewidth,
                                                   tick0=0,
                                                   dtick=0.5,
                                                   ticklen=5,
                                                   tickwidth=1,
                                                   tickfont=dict(size=self.cb_tickfontsize,
                                                                 color=self.color,
                                                                 family=self.font),
                                                   title=self.cb_title)
                                     ),
                        layout=layout)

        # Makeup
        fig.update_layout(
            title={'text': '<b>'+plot_title+'<b>' if title_bold is True else plot_title,
                   'x': 0.5,
                   'y': title_y,
                   'xanchor': 'center',
                   'yanchor': 'top'},
            font=dict(
                family=self.font,
                size=title_size,
                color=self.color,
            )
        )

        fig.show()

        if not isinstance(filename, type(None)):
            self.save(fig=fig, filename=filename)
Exemplo n.º 14
0
from plotly.offline import plot
import plotly.graph_objs as go
import numpy as np

plot_data = np.load('plot.npy')
cam_R = plot_data[()]['cam_R']
cam_t = plot_data[()]['cam_t']
verts = plot_data[()]['verts']
faces = plot_data[()]['faces']
voxels_value_flatten = plot_data[()]['voxel_value']
object_point_3D = plot_data[()]['object_point']

trace_object = go.Mesh3d(x=verts[:,0],y=verts[:,1],z=verts[:,2],i=faces[:,0],j=faces[:,1],k=faces[:,2])
trace_camera = go.Cone()
#trace_cube = go.Volume(x=,y=object_point_3D[1,:],z=object_point_3D[2,:],value=voxels_value_flatten)

# try to using plotly to imshow 3d mesh and camera pose
x,y,z=zip(*verts)
trace_point = go.Scatter3d(x=x,y=y,z=z,mode='markers',
    marker=dict(
        color='rgb(0, 0, 255)',
        size=2,
        symbol='circle',
        line=dict(
            color='rgb(204, 204, 204)',
            width=1
        ),
        opacity=0.9
    ))
plot([trace_point, trace_object])
print('fdsa')
Exemplo n.º 15
0
def vector_plot(result, titles, verbose=False, **kwargs):
    variable = titles['variable']
    val0 = list(result.values())[0]

    if (result[variable].shape == val0.shape) & (val0.shape[1] == 2):
        if verbose:
            print('\t 2-d output', result[variable].shape)
        u = result[variable][:, 0]
        v = result[variable][:, 1]
        x = val0[:, 0]
        y = val0[:, 1]

        trace = ff.create_quiver(
            x,
            y,
            u,
            v,
            # scale=.25,
            # arrow_scale=.4,
            name='quiver',
            line=dict(width=1))['data'][0]  # extracts quiver trace

        layout = go.Layout(title=titles['title'],
                           xaxis=dict(title='x'),
                           yaxis=dict(title='y'))
        chart_type = '2d-vector'

    elif (result[variable].shape == val0.shape) & (val0.shape[1] == 3):
        if verbose:
            print('\t 3-d output', result[variable].shape, val0.shape)
            print('\t 3d vector plot')
        if type(result[variable]) == pd.DataFrame:
            u = result[variable].values[:, 0].tolist()
            v = result[variable].values[:, 1].tolist()
            w = result[variable].values[:, 2].tolist()
        else:
            u = result[variable][:, 0].tolist()
            v = result[variable][:, 1].tolist()
            w = result[variable][:, 2].tolist()
        if type(val0) == pd.DataFrame:
            x = val0.values[:, 0].tolist()
            y = val0.values[:, 1].tolist()
            z = val0.values[:, 2].tolist()
        else:
            x = val0[:, 0].tolist()
            y = val0[:, 1].tolist()
            z = val0[:, 2].tolist()
        norms = np.linalg.norm(result[variable], axis=1)
        trace = go.Cone(
            x=x,
            y=y,
            z=z,
            u=u,
            v=v,
            w=w,
            hoverinfo='x+y+z+u+v+w+norm',
            colorscale='Reds',
            cmin=0,
            cmax=norms.max(),
        )

        layout = go.Layout(title=titles['title'],
                           scene=dict(
                               xaxis=dict(title='x'),
                               yaxis=dict(title='y'),
                               zaxis=dict(title='z'),
                           ))
        chart_type = '3d-vector'
    else:
        raise NotImplementedError('plot type not supported yet')

    return [trace], chart_type, layout
Exemplo n.º 16
0
def generate_scatterplot_3D(
    word_vectors,
    user_input=None,
    words=None,
    annotation="On",
    dim_red="PCA",
    perplexity=0,
    learning_rate=0,
    iteration=0,
    topn=0,
):
    if dim_red == "PCA":
        three_dim = calc_3d_pca(word_vectors)
    else:
        three_dim = calc_3d_tsne(word_vectors, perplexity, learning_rate,
                                 iteration)

    color = "blue"
    quiver = go.Cone(
        x=[0, 0, 0],
        y=[0, 0, 0],
        z=[0, 0, 0],
        u=[1.5, 0, 0],
        v=[0, 1.5, 0],
        w=[0, 0, 1.5],
        anchor="tail",
        colorscale=[[0, color], [1, color]],
        showscale=False,
    )

    data = [quiver]

    count = 0
    for i in range(len(user_input)):

        trace = go.Scatter3d(
            x=three_dim[count:count + topn, 0],
            y=three_dim[count:count + topn, 1],
            z=three_dim[count:count + topn, 2],
            text=words[count:count + topn] if annotation == "On" else "",
            name=user_input[i],
            textposition="top center",
            textfont_size=30,
            mode="markers+text",
            marker={
                "size": 10,
                "opacity": 0.8,
                "color": 2
            },
        )

        data.append(trace)
        count = count + topn

    trace_input = go.Scatter3d(
        x=three_dim[count:, 0],
        y=three_dim[count:, 1],
        z=three_dim[count:, 2],
        text=words[count:],
        name="input words",
        textposition="top center",
        textfont_size=30,
        mode="markers+text",
        marker={
            "size": 10,
            "opacity": 1,
            "color": "black"
        },
    )

    data.append(trace_input)

    # Configure the layout.
    layout = go.Layout(
        margin={
            "l": 0,
            "r": 0,
            "b": 0,
            "t": 0
        },
        showlegend=True,
        legend=dict(x=1,
                    y=0.5,
                    font=dict(family="Courier New", size=24, color="black")),
        font=dict(family=" Courier New ", size=15),
        autosize=False,
        width=800,
        height=600,
    )

    return go.Figure(data=data, layout=layout)
Exemplo n.º 17
0
    def quiverly(self,
                 *args,
                 fig=None,
                 showarrow=True,
                 color="black",
                 scale=5,
                 origin=None,
                 arrow_size='scaled',
                 line_kwargs=None,
                 name='Vector',
                 showlegend=False):
        """
        """
        if origin is None:
            origin = np.zeros(3)

        assert isinstance(self, Vector)

        import plotly.graph_objs as go
        x = np.stack([0, self[0].squeeze()]) + origin[0]
        y = np.stack([0, self[1].squeeze()]) + origin[1]

        color_scale = [[0, color], [1, color]]

        if fig is None:
            fig = go.Figure()

        if len(self) == 2:
            z = np.zeros_like(x) + origin[2]
        else:
            z = np.stack([0, self[2].squeeze()]) + origin[2]

        if arrow_size == 'scaled':
            u = [(x[1] - x[0]) / scale]
            v = [(y[1] - y[0]) / scale]
            w = [(z[1] - z[0]) / scale]
        elif isinstance(arrow_size, (int, float)):
            du = (x[1] - x[0])
            dv = (y[1] - y[0])
            dz = (z[1] - z[0])
            mag_du = np.sqrt(du**2 + dv**2 + dz**2)
            u = [du / mag_du * arrow_size]
            v = [dv / mag_du * arrow_size]
            w = [dz / mag_du * arrow_size]
        else:
            raise Exception(
                "size must either be set to scaled or an int or float")

        obj = go.Scatter3d(x=x,
                           y=y,
                           z=z,
                           marker=dict(size=0),
                           line=dict(color=color),
                           name=name,
                           showlegend=showlegend)

        cone = go.Cone(x=[x[1]],
                       y=[y[1]],
                       z=[z[1]],
                       u=u,
                       v=v,
                       w=w,
                       colorscale=color_scale,
                       showscale=False,
                       name=None)

        fig.add_trace(obj)
        fig.add_trace(cone)
        return fig, obj
Exemplo n.º 18
0
def plot_3D_quiver(pts_world: Union[Dict, torch.Tensor],
                   pts_world_grad: Union[Dict, torch.Tensor],
                   mesh_gt: Optional[Meshes] = None,
                   mesh: List[trimesh.Trimesh] = None,
                   camera: CamerasBase = None,
                   n_debug_points: int = -1,
                   save_html: Optional[str] = None) -> go.Figure:
    """
    Plot 3D quiver plots (cone), for each point, plot the normalized negative gradient.
    Accept dictionaries of {str: tensor(N,3)} or tensors (N,3). In case dictionaries are proviced,
    the keys are used for hovertext, otherwise, the indices of points are used.
    Args:
        pts_world (tensor):
        pts_world_grad (tensor): the vector projected to world space, i.e. proj(pts+grad) - pts_world
        mesh_gt (Meshes): (H,W) image value range [0,1]
        save_html (str): If given, then save to file
    """
    n_pts_per_cat = None
    text_to_id = None
    if isinstance(pts_world, torch.Tensor):
        n_pts_per_cat = OrderedDict(all=pts_world.shape[0])
        if n_debug_points > 0:
            n_pts_per_cat['all'] = min(n_debug_points, n_pts_per_cat['all'])

        pts_world = pts_world.cpu()[:n_pts_per_cat['all']]
        pts_world_grad = pts_world_grad.cpu()[:n_pts_per_cat['all']]
        text = np.array([str(i) for i in range(pts_world.shape[0])])

    elif isinstance(pts_world, dict):
        n_pts_per_cat = OrderedDict(
            (k, (pts.shape[0])) for k, pts in pts_world.items())
        if n_debug_points > 0:
            for k in n_pts_per_cat:
                n_pts_per_cat[k] = min(n_debug_points, n_pts_per_cat[k])

        text_to_id = {k: i for i, k in enumerate(pts_world)}
        pts_world = torch.cat(
            [pts_world[k][:v] for k, v in n_pts_per_cat.items()], dim=0)
        pts_world_grad = torch.cat(
            [pts_world_grad[k][:v] for k, v in n_pts_per_cat.items()], dim=0)
        pts_world = pts_world.cpu()
        pts_world_grad = pts_world_grad.cpu()
        text = np.array(
            [k for k, pts in n_pts_per_cat.items() for i in range(pts)])

    # one 3D plot for the pts_world
    fig3D = go.Figure()
    # log scale pts_world_grad and clip grad with very large norms
    grad_norm = torch.norm(pts_world_grad, dim=-1, keepdim=True)
    pts_world_grad_normalized = torch.nn.functional.normalize(pts_world_grad)

    # plot Scatter3D with different colors
    if len(n_pts_per_cat) > 1 and pts_world.shape[0] > 0:
        # plot all pts and grad together
        t0 = time.time()
        fig3D.add_trace(
            go.Cone(
                x=pts_world.cpu().numpy()[:, 0],
                y=pts_world.cpu().numpy()[:, 1],
                z=pts_world.cpu().numpy()[:, 2],
                u=-pts_world_grad.cpu().numpy()[:, 0],
                v=-pts_world_grad.cpu().numpy()[:, 1],
                w=-pts_world_grad.cpu().numpy()[:, 2],
                customdata=grad_norm.cpu().numpy(),
                name='all',
                visible=True,
                anchor='tail',
                text=text,
                hovertemplate=
                '<b>%{text}</b> ||Fp|| = %{customdata} <extra></extra>',
                sizemode="scaled",  # absolute|scaled
                sizeref=1.0,
                showscale=False,
                colorscale='Reds'))
        t1 = time.time()
        # print('Cone All {:.3f}'.format(t1-t0))
    # plot gradients
    _start_pts = 0
    for k, n_pts in n_pts_per_cat.items():
        pts = pts_world[_start_pts:(n_pts + _start_pts)].cpu().numpy()
        grad = pts_world_grad[_start_pts:(n_pts + _start_pts)].cpu().numpy()
        norm = grad_norm[_start_pts:(n_pts + _start_pts)].cpu().numpy()
        _start_pts += n_pts
        if pts.size == 0:
            continue
        t0 = time.time()
        fig3D.add_trace(
            go.Cone(
                x=pts[:, 0],
                y=pts[:, 1],
                z=pts[:, 2],
                u=-grad[:, 0],
                v=-grad[:, 1],
                w=-grad[:, 2],
                customdata=norm,
                name=k + ' grad',
                visible=False,
                anchor='tail',
                hovertemplate='||Fp|| = %{customdata} <extra></extra>',
                sizemode="scaled",  # absolute|scaled
                sizeref=1,
                showscale=False,
                colorscale='Reds'))
        t1 = time.time()
        # print('Cone {} {:.3f}'.format(k, t1-t0))
    # plot all sampled points
    _start_pts = 0
    for k, n_pts in n_pts_per_cat.items():
        pts = pts_world[_start_pts:(n_pts + _start_pts)].cpu().numpy()
        _start_pts += n_pts
        if pts.size == 0:
            continue
        t0 = time.time()
        fig3D.add_trace(
            go.Scatter3d(
                x=pts[:, 0],
                y=pts[:, 1],
                z=pts[:, 2],
                name=k,
                visible=False,
                mode='markers',
                marker_size=5,
            ))
        t1 = time.time()
        # print('Scatter3d {} {:.3f}'.format(k, t1-t0))

    # make first plot visible
    fig3D.data[0].visible = True

    # plot ground truth mesh
    # TODO(yifan): toggle visibility
    n_always_visible_plots = 0
    if mesh_gt is not None:
        t0 = time.time()
        fig3D.add_trace(
            go.Mesh3d(x=mesh_gt.verts_list()[0][:, 0],
                      y=mesh_gt.verts_list()[0][:, 1],
                      z=mesh_gt.verts_list()[0][:, 2],
                      i=mesh_gt.faces_list()[0][:, 0],
                      j=mesh_gt.faces_list()[0][:, 1],
                      k=mesh_gt.faces_list()[0][:, 2],
                      name='mesh_gt',
                      opacity=0.5,
                      color='gold'))
        t1 = time.time()
        # print('Mesh GT {:.3f}'.format(t1-t0))
        n_always_visible_plots += 1

    # plot predicted mesh
    # TODO(yifan): toggle visibility
    if mesh is not None and not mesh.is_empty:
        t0 = time.time()
        fig3D.add_trace(
            go.Mesh3d(x=mesh.vertices[:, 0],
                      y=mesh.vertices[:, 1],
                      z=mesh.vertices[:, 2],
                      i=mesh.faces[:, 0],
                      j=mesh.faces[:, 1],
                      k=mesh.faces[:, 2],
                      name='predicted surface',
                      opacity=0.2,
                      color='lightgray',
                      hoverinfo='name'))
        t1 = time.time()
        # print('Mesh Predicted {:.3f}'.format(t1-t0))
        n_always_visible_plots += 1

    menu_buttons = []
    for i, trace in enumerate(fig3D.data):
        visibles = [False] * len(fig3D.data)
        visibles[i] = True
        for p in range(n_always_visible_plots):
            visibles[len(fig3D.data) - p - 1] = True
        menu_buttons.append({
            'label':
            trace.name,
            'args': [{
                'visible': visibles
            }, {
                'title': trace.name
            }],
            'method':
            'update'
        })
    cam_up = camera.get_full_projection_transform().inverse().get_matrix()[
        0, 1, :3].tolist()
    cam_up = dict(x=cam_up[0], y=cam_up[1], z=cam_up[2])
    cam_eye = camera.get_camera_center()[0, :].tolist()
    cam_eye = dict(x=cam_eye[0], y=cam_eye[1], z=cam_eye[2])

    fig3D.update_layout(updatemenus=[dict(
        active=0,
        buttons=menu_buttons,
    )],
                        scene=dict(xaxis=dict(range=[-1.2, 1.2],
                                              autorange=False),
                                   yaxis=dict(range=[-1.2, 1.2],
                                              autorange=False),
                                   zaxis=dict(range=[-1.2, 1.2],
                                              autorange=False),
                                   aspectratio=dict(x=1, y=1, z=1),
                                   camera=dict(up=cam_up,
                                               center=dict(x=0, y=0, z=0),
                                               eye=cam_eye)))
    if save_html is not None:
        os.makedirs(os.path.dirname(save_html), exist_ok=True)
        # figures_to_html([fig3D], save_html)
        fig3D.write_html(save_html)
    return fig3D
Exemplo n.º 19
0
def genereate_json_for_3d_graph():
    '''
    this function create the json file that is used by plotly to create the figure 
    for the 3d visualization
    OUTPUT: string in the form of a json file
    '''

    import pandas as pd
    import networkx as nx
    import json
    import plotly.graph_objs as go
    import plotly
    import random

    random.seed(10)

    # import data
    df_edges = pd.read_excel("raan_case_study.xlsx", sheet_name=0)
    df_nodes = pd.read_excel("raan_case_study.xlsx", sheet_name=1)

    # create graph (create 2 lists dictionary with the edges and with the nodes and their attributes)
    edges_list = [(el[0], el[1], el[2]) for _, el in df_edges.T.items()]
    nodes_list = [(el[0], {
        'color': el[1],
        'label': el[2]
    }) for _, el in df_nodes.T.items()]

    # create graph
    G = nx.DiGraph()

    # add nodes and edges to graph
    G.add_nodes_from(nodes_list)
    G.add_weighted_edges_from(edges_list)

    # get positions of nodes in 3D plane
    pos = nx.layout.spring_layout(G, dim=3)
    Xn = [pos[el][0] for el in pos]  # x-coordinates of nodes
    Yn = [pos[el][1] for el in pos]  # y-coordinates
    Zn = [pos[el][2] for el in pos]  # z-coordinates

    # creates lists with attributes of nodes
    names_list = [el[1]['label'] for el in G.nodes(data=True)]  # labels
    attr_list = [(el[0], el[1]['label'])
                 for el in G.nodes(data=True)]  # id and label
    id_list = [el[0] for el in G.nodes(data=True)]  # id
    color_list = [el[1]['color'] for el in G.nodes(data=True)]  # colors

    # 3D plot of the graph

    # interactive 3D plot
    # create list of position of cones and direction of edges
    # position of the cones
    Xs = [0.55 * pos[el[1]][0] + 0.45 * pos[el[0]][0] for el in G.edges()]
    Ys = [0.55 * pos[el[1]][1] + 0.45 * pos[el[0]][1] for el in G.edges()]
    Zs = [0.55 * pos[el[1]][2] + 0.45 * pos[el[0]][2] for el in G.edges()]
    # direction of the cones
    Us = [pos[el[1]][0] - pos[el[0]][0] for el in G.edges()]
    Vs = [pos[el[1]][1] - pos[el[0]][1] for el in G.edges()]
    Ws = [pos[el[1]][2] - pos[el[0]][2] for el in G.edges()]

    trace1 = go.Scatter3d(x=Xn,
                          y=Yn,
                          z=Zn,
                          mode='text+markers',
                          name='nodes',
                          text=id_list,
                          marker=dict(symbol='circle',
                                      size=10,
                                      color=color_list,
                                      line=dict(color='rgb(50,50,50)',
                                                width=0.5)),
                          textposition="bottom center",
                          meta=attr_list,
                          hoverinfo='text',
                          hovertext=names_list)

    # set axis for plot
    axis = dict(showbackground=False,
                showline=False,
                zeroline=False,
                showgrid=False,
                showticklabels=True,
                title='')

    # set layout for plot
    layout = go.Layout(
        title="",
        width=1000,
        height=1000,
        showlegend=False,
        scene=dict(xaxis=dict(axis), yaxis=dict(axis), zaxis=dict(axis)),
        margin=dict(t=100),
        hovermode='closest',
        annotations=[
            dict(showarrow=False,
                 text="",
                 xref='paper',
                 yref='paper',
                 x=0,
                 y=0.1,
                 xanchor='left',
                 yanchor='bottom',
                 font=dict(size=14))
        ],
    )

    # create figure
    data = [trace1]
    fig = go.Figure(data=data, layout=layout)

    # plotly does not allow to draw directe arrow
    # to show the direction of the edge in the direction of the edge is plotted in the middle of the edge

    # create trace for cones (used to indicate direction of edge)
    # hovering over the edge source and target nodes as well as the
    trace = go.Cone(x=Xs,
                    y=Ys,
                    z=Zs,
                    u=Us,
                    v=Vs,
                    w=Ws,
                    opacity=0.4,
                    showscale=False,
                    colorscale=[[0, 'rgb(125,125,125)'],
                                [1, 'rgb(125,125,125)']],
                    hoverinfo='text',
                    text=[
                        'edge from ' + str(G.nodes(data=True)[e[0]]['label']) +
                        ' (' + str(e[0]) + ') ' + ' to ' +
                        str(G.nodes(data=True)[e[1]]['label']) + ' (' +
                        str(e[1]) + ') ' + ': weight: ' + str(e[2]['weight'])
                        for e in G.edges(data=True)
                    ])

    fig.add_trace(trace)

    # get list of weights
    weights_list = [el[2]['weight'] for el in G.edges(data=True)]
    # use a frozenset to get the distinct elements (use frozenset because it is iterable)
    unique_weights = frozenset(weights_list)

    # loop over different weights and insert edges with corresponding width proportional to the weigth
    for el in unique_weights:
        filtered_edges = [
            e[0:2] for e in G.edges(data=True) if e[2]['weight'] == el
        ]  # filter out edges with a certain weight
        Xe = []
        Ye = []
        Ze = []

        # create lists of position of the nodes of filtered edges (add none after every 2 coordinates)
        for e in filtered_edges:
            Xe += [pos[e[0]][0], pos[e[1]][0], None]
            Ye += [pos[e[0]][1], pos[e[1]][1], None]
            Ze += [pos[e[0]][2], pos[e[1]][2], None]

        # create trace with filtered edges (line wwidth = 1.5 * edge weight)
        trace2 = go.Scatter3d(x=Xe,
                              y=Ye,
                              z=Ze,
                              mode='lines',
                              name=str(el),
                              line=dict(color='rgb(125,125,125)',
                                        width=el * 1.5),
                              hoverinfo='text',
                              textposition='middle right')
        # add trace to figure
        fig.add_trace(trace2)

        # create json from figure
        full_json = plotly.io.to_json(fig)
        # transform json to dict to perform operations on it
        full_dict = json.loads(full_json)

        # extact values relative to data and layout keys
        data = json.dumps(full_dict['data'])
        layout = json.dumps(full_dict['layout'])

        # concatenate the 2
        graphJSON = data + ',' + layout

    return graphJSON