Karel Macek
Karel Macek

Reputation: 1189

Fast oriented graphs in bokeh

To plot a graph (networkx.DiGraph), I am using the following code (looping over all edges):

arrow = Arrow(end=OpenHead(line_color=color, line_width=12, size=14),
                  y_start=pos[from_node][1],
                  x_start=pos[from_node][0],
                  x_end=pos[to_node][0],
                  y_end=pos[to_node][1],
                  line_color=color, line_width=12)
plot.add_layout(arrow)

I would like to use multi_line instead of this, but there is no way how to add arrows. Or is there any?

Upvotes: 2

Views: 2353

Answers (2)

VMAtm
VMAtm

Reputation: 28355

As far as I can see in tutorials and github code, the multi_line function wasn't intended to be a graph drawing function, and should be used only for linear data plot, just with more than one data source.

However, that function accepts LineProps object, so you can try out to adjust it to your needs. For now, line options are:

  • line_color
  • line_width
  • line_alpha
  • line_join
  • line_cap
  • line_dash
  • line_dash_offset

I suggest you to try out the line_join property, with possible values:

  • 'miter' enter image description here
  • 'round' enter image description here
  • 'bevel' enter image description here

So the method could be something like this:

from bokeh.plotting import figure, output_file, show

p = figure(plot_width=300, plot_height=300)
p.multi_line(xs=[[1, 2, 3], [2, 3, 4]], ys=[[6, 7, 2], [4, 5, 7]],
             color=['red','green'], line_join='miter')
show(p)

Complete reference for bokeh.plotting can be found here.

Upvotes: 1

Menglong Li
Menglong Li

Reputation: 2255

I once use networkx to genearte a graph with 'Arrow', actually not a real arrow, but can be treated like one:enter image description here

The codes that genearate this is to implement a Kosaraju–Sharir algorithm (find strongly connected components); The main codes is as following:

def generate_G():
    G = defaultdict(set)
    G['a'] = {'b', 'c'}
    G['b'] = {'d', 'e', 'i'}
    G['c'] = {'d'}
    G['d'] = {'a', 'h'}
    G['e'] = {'f'}
    G['f'] = {'g'}
    G['g'] = {'e', 'h'}
    G['h'] = {'i'}
    G['i'] = {'h'}
    return G

def draw_G(raw_G):
    import networkx as nx
    import matplotlib
    # generate postscript output by default from http://matplotlib.org/faq/usage_faq.html#what-is-a-backend
    matplotlib.use('PS')
    import matplotlib.pyplot as plt
    import pylab
    G = nx.DiGraph()
    G.add_nodes_from(raw_G.keys())
    G.add_edges_from([(u, v) for u in raw_G for v in raw_G[u]], weight=1)
    pos = nx.spring_layout(G)
    edge_labels = dict([((u, v,), d['weight'])
                    for u, v, d in G.edges(data=True)])
    nx.draw_networkx_edges(G, pos, alpha=0.3)
    nx.draw(G, pos=pos, node_size=250, with_labels=True, )
    plt.axis('off')
    plt.savefig("kosaraju.png")

if __name__ == "__main__":
    raw_G = generate_G()
    draw_G(raw_G)

The complete codes could be found at my github, if you're interested: https://github.com/albertmenglongli/Algorithms/blob/master/PythonAlgrithoms/kosaraju.py, and the image generated is here: https://github.com/albertmenglongli/Algorithms/blob/master/PythonAlgrithoms/kosaraju.png

I tried to implement many algrothims but in a more engineering way, if anyone who is interested.

Upvotes: 1

Related Questions