Plotly Sankey: why are nodes misplaced?

Viewed 146

(Plotly 4.10.0, Python 3.8.0, Ubuntu 20.04)

I am working with Plotly Sankeys, but automatic placement looks quite buggy (alas I cannot place the nodes manually).

import plotly.graph_objects as go

sources = [ 0,  0,  1,  1,  2,  2]
targets = [ 1,  2,  3,  4,  5,  6]
values  = [45, 30, 15, 30, 20, 10]
labels = ['Node 0', 'Node 1', 'Node 2', 'Node 3', 'Node 4', 'Node 5', 'Node 6']

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

wrong placement

Why is Node 3 misplaced, and is not together with Node 4? Nodes are not placed according to sorted value, otherwise Node 3 should be below Node 6.

Just changing from 15 to 16 the weight of Node1->3 the placement is correct:

values  = [46, 30, 16, 30, 20, 10]

produces:

correct placement

Am I missing something here?

-----------------------------------------

EDIT: Is node_pad the culprit?

The original

values  = [45, 30, 15, 30, 20, 10]
...
data = go.Sankey(link=link, node=node)

returns a faulty placement.

data = go.Sankey(link=link, node=node, node_pad=9) solves the problem.

With data = go.Sankey(link=link, node=node, node_pad=10) it manifests again.

It looks like a bug in calculations. I will open an issue.

1 Answers

I cannot reproduce this issue, so my guess is that the newest update to Plotly v4.10.0 may have fixed this bug.

import plotly.graph_objects as go

sources = [0,  0,  1,  1,  2,  2] #indices correspond to labels
targets = [1,  2,  3,  4,  5,  6] 
values  = [45, 30, 15, 30, 20, 10]
labels = ['Node 0', 'Node 1', 'Node 2', 'Node 3', 'Node 4', 'Node 5', 'Node 6']

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()
# fig.show(renderer="svg", width=1000, height=500)

enter image description here

If I drastically alter some of the values, as you said, we shouldn't expect the node placement to change. values = [20, 30, 25, 30, 20, 10] does not change the placement of the nodes for me:

enter image description here

Related