5

Plotly Sankeys fill all the available space.

If some "branches" have 3 levels (Node 0 -> Node 1 -> Node 3) and others only two (Node 0 -> Node 2), the final nodes (Node 2 and Node 3) are vertically aligned to the right.
I would like to be able to align vertically Node 1 (not Node 3!) and Node 2, as in the second figure in attachment.

It is quite difficult for me to align all nodes programmatically, so I would like to avoid this possibility.

Even in the former undesired case something goes wrong (code for Jupyter Lab):

import plotly.graph_objects as go

sources = [ 0,  0,  1,  1]
targets = [ 1,  2,  3,  4]
values  = [59, 30, 29, 30]

labels = ['Node 0', 'Node 1', 'Node 2', 'Node 3', 'Node 4']

link = dict(source=sources, target=targets, value=values)
node = dict(label=labels)
data = go.Sankey(link=link, node=node)
fig = go.Figure(data)
fig.show(renderer="svg", width=1000, height=500)

produces:

default wrong placement

It looks like there is a bug when placing Node 1 that doesn't take in account the thickness of Node0->2 flow.

Is it possible to tell that I want Node 2 on the same vertical line of Node 1, and that Node 2 has no children? A solution would be the manual placement, alas I cannot do it because my Sankey is highly dynamic.

As a workaround I created a dummy node after Node 2, and made it invisible:

import plotly.graph_objects as go

sources = [ 0,  0,  1,  1, 2]
targets = [ 1,  2,  3,  4, 5]
values  = [59, 30, 29, 30, 30]
labels = ['Node 0', 'Node 1', 'Node 2', 'Node 3', 'Node 4']

color_links = ["lightgray", "lightgray", "lightgray", "lightgray", "white"]
color_nodes = ["red", "blue", "green", "navy", "lightgreen", "white"]

link = dict(source=sources, target=targets, value=values, color=color_links)
node = dict(label=labels, color=color_nodes, line = dict(width = 0))
data = go.Sankey(link=link, node=node)
fig = go.Figure(data)
fig.show(renderer="svg", width=1000, height=500)

this produces:

clumsy workaround

I would expect a better and easier way to do this. Is there any pointer to a working demo?

Alex Poca
  • 2,406
  • 4
  • 25
  • 47
  • It doesn't sound like it, but would it be acceptable to specify node positions in a dict? – vestland Jan 18 '21 at 16:19
  • Alas, no: their position should changes during animation. I saw that D3.js has the same problem (first two figures, the one on the right): https://www.d3-graph-gallery.com/sankey – Alex Poca Jan 19 '21 at 12:48
  • If animation is a key element here, perhaps you should consider stating that in the question? – vestland Jan 19 '21 at 12:51
  • I cannot know in advance a proper position for each node, and animation is just a factor that makes things more difficult to manage, not the issue at hand. I found a lot of issues with the Sankey in Plotly: two more are flow lines overlapping each other (poor autopositioning) and autosort of nodes based on their value (instead of the add order that would be more flexible). – Alex Poca Jan 19 '21 at 12:53

0 Answers0