123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- def build_plotly_figure(self, pos=None):
- """
- Creates a Plot.ly Figure that can be view online or offline.
- Parameters
- ----------
- graph : nx.Graph
- The network of zettels to visualize
- pos : dict
- Dictionay of zettel_id : (x, y) coordinates where to draw nodes. If
- None, the Kamada Kawai layout will be used.
- Returns
- -------
- fig : plotly Figure
- """
- if pos is None:
- # The kamada kawai layout produces a really nice graph but it's
- # a O(N^2) algorithm. It seems only reasonable to draw the graph
- # with fewer than ~1000 nodes.
- if len(self.graph) < 1000:
- pos = nx.layout.kamada_kawai_layout(self.graph)
- else:
- pos = nx.layout.random_layout(self.graph)
- # Create scatter plot of the position of all notes
- node_trace = go.Scatter(
- x=[],
- y=[],
- text=[],
- mode="markers",
- hoverinfo="text",
- marker=dict(
- showscale=True,
- # colorscale options
- #'Greys' | 'YlGnBu' | 'Greens' | 'YlOrRd' | 'Bluered' | 'RdBu' |
- #'Reds' | 'Blues' | 'Picnic' | 'Rainbow' | 'Portland' | 'Jet' |
- #'Hot' | 'Blackbody' | 'Earth' | 'Electric' | 'Viridis' |
- colorscale="YlGnBu",
- reversescale=True,
- color=[],
- size=10,
- colorbar=dict(
- thickness=15, title="Centrality", xanchor="left", titleside="right"
- ),
- line=dict(width=2),
- ),
- )
- for node in self.graph.nodes():
- x, y = pos[node]
- text = "<br>".join([node, self.graph.nodes[node].get("title", "")])
- node_trace["x"] += tuple([x])
- node_trace["y"] += tuple([y])
- node_trace["text"] += tuple([text])
- # Color nodes based on the centrality
- for node, centrality in nx.degree_centrality(self.graph).items():
- node_trace["marker"]["color"] += tuple([centrality])
- # Draw the edges as annotations because it's only sane way to draw arrows.
- edges = []
- for from_node, to_node in self.graph.edges():
- edges.append(
- dict(
- # Tail coordinates
- ax=pos[from_node][0],
- ay=pos[from_node][1],
- axref="x",
- ayref="y",
- # Head coordinates
- x=pos[to_node][0],
- y=pos[to_node][1],
- xref="x",
- yref="y",
- # Aesthetics
- arrowwidth=2,
- arrowcolor="#666",
- arrowhead=2,
- # Have the head stop short 5 px for the center point,
- # i.e., depends on the node marker size.
- standoff=5,
- )
- )
- fig = go.Figure(
- data=[node_trace],
- layout=go.Layout(
- showlegend=False,
- hovermode="closest",
- margin=dict(b=20, l=5, r=5, t=40),
- annotations=edges,
- xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
- yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
- ),
- )
- return fig
|