Question: Working with Networkx, I have several edges that need to be displayed in different ways. For that I use the connectionstyle, some edges are straight lines, some others are Arc3. The problem is that every edge has a label and the label doesn't follow the edges in these styles. I borrowed a graph as example :  #!/usr/bin/env python3 import networkx as nx import matplotlib.pyplot as plt # Graph data names = ['A', 'B', 'C', 'D', 'E'] positions = [(0, 0), (0, 1), (1, 0), (0.5, 0.5), (1, 1)] edges = [('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('D', 'A')] # Matplotlib figure plt.figure('My graph problem') # Create graph G = nx.MultiDiGraph(format='png', directed=True) for index, name in enumerate(names): G.add_node(name, pos=positions[index]) labels = {} for edge in edges: G.add_edge(edge[0], edge[1]) labels[(edge[0], edge[1])] = '{} -> {}'.format(edge[0], edge[1]) layout = dict((n, G.node[n]["pos"]) for n in G.nodes()) nx.draw(G, pos=layout, with_labels=True, node_size=300, connectionstyle='Arc3, rad=0.3') nx.draw_networkx_edge_labels(G, layout, edge_labels=labels, connectionstyle='Arc3, rad=0.3') # Here is the problem : the labels will not follow the edges plt.show()  That can lead to problems as shows this example image : we're not sure for which edge is the label. Is there a way to draw labels that follow their edges ? Thanks

Answer: Yes, it is possible to draw labeled edges of networkx directed graphs, by using GraphViz. An example using the Python package graphviz, the Python package networkx, and the GraphViz program dot: """How to draw a NetworkX graph using GraphViz. Requires: - The Python package `graphviz`: https://github.com/xflr6/graphviz `pip install graphviz` - The Python package `networkx`: https://github.com/xflr6/graphviz `pip install networkx` - The GraphViz program `dot` in the environment's path https://graphviz.org/download/ https://en.wikipedia.org/wiki/PATH_(variable) """ import graphviz as gv import networkx as nx def dump_example_directed_graph(): """Use GraphViz `dot` to layout a directed multigraph. Creates a file named 'example_directed_graph' that contains the rendered graph. """ g = example_directed_graph() h = networkx_to_graphviz(g) filename = 'example_directed_graph' fileformat = 'pdf' h.render(filename, format=fileformat, cleanup=True) # The argument `view=True` can be given to # the method `graphviz.dot.Digraph.render` # to open the rendered file with the # default viewer of the operating system def dump_example_undirected_graph(): """Use GraphViz `dot` to layout an undirected multigraph. Creates a file named `example_undirected_graph` that contains the rendered graph. """ g = example_undirected_graph() h = networkx_to_graphviz(g) filename = 'example_undirected_graph' fileformat = 'pdf' h.render(filename, format=fileformat, cleanup=True) def example_directed_graph(): """Return a sample directed graph as `networkx.MultiDiGraph`.""" g = nx.MultiDiGraph() g.add_node(1, label='A') g.add_node(2, label='B') g.add_edge(1, 2, label='AB-1') g.add_edge(1, 2, label='AB-2') g.add_edge(2, 1, label='BA') return g def example_undirected_graph(): """Return a sample undirected graph as `networkx.MultiGraph`.""" g = nx.MultiGraph() g.add_node(1, label='A') g.add_node(2, label='B') g.add_edge(1, 2, label='AB-1') g.add_edge(1, 2, label='AB-2') return g def networkx_to_graphviz(g): """Convert `networkx` graph `g` to `graphviz.Digraph`. @type g: `networkx.Graph` or `networkx.DiGraph` @rtype: `graphviz.Digraph` """ if g.is_directed(): h = gv.Digraph() else: h = gv.Graph() for u, d in g.nodes(data=True): h.node(str(u), label=d['label']) for u, v, d in g.edges(data=True): h.edge(str(u), str(v), label=d['label']) return h if __name__ == '__main__': dump_example_directed_graph() dump_example_undirected_graph()  Documentation of the:  class graphviz.dot.Graph for representing undirected graphs class graphviz.dot.Digraph for representing directed graphs method graphviz.dot.Digraph.node for adding an annotated node to a graph method graphviz.dot.Digraph.edge for adding an annotated edge to a graph class networkx.MultiGraph for representing undirected graphs class networkx.MultiDiGraph for representing directed graphs  The above code uses networkx == 2.5.1, graphviz == 0.16, and GraphViz version 2.40.1. Current possibilities using matplotlib It appears that currently networkx supports:  unlabeled curved edges using the function networkx.drawing.nx_pylab.draw_networkx_edges with the argument connectionstyle, or labeled straight edges using the function networkx.drawing.nx_pylab.draw_networkx_edges with the argument edge_labels.  So as of networkx <= 2.5.1, labeled curved edges cannot be drawn with matplotlib. As a result, for a directed graph with a pair of labeled edges that connect the same nodes (e.g., an edge 1 -> 2 and an edge 2 -> 1), the edges would be drawn in matplotlib to overlap, so not all edge labels will be visible.