Sankey chart in plotly: need to arrange my nodes as columns. Is this possible without messing with x and y?

Could someone with knowledge of Sankey-charts please help?

I am creating a sankey-chart that has nodes of 4 different categories. I need the 1st group of nodes to be displayed on the left one under another, then the 2nd group should be to the right, etc.

This actually works like a charm out of the box, but ONLY if my nodes are interconnected in such a way that a line can be drawn to trace links from node-of-category1 -- > to node-of-category2 --> to node of category3 --> to node of category 4.

Unfortunately it's not always the case with my data. Some of the connections are "shorter" and include only 2 or 3 nodes.

What happens as a result is that if there's no link between some node from 3rd-column & node from 4th-column, that node is shifted to the very right , and becomes aligned to 4th column.

I tried different things and found that I could accomplish it with providing x and y coordinates for each node. That's fine, but i feel that my implementation of this will be messy, because the underlying data is different each time, hence i need to do a lot work to come up with y-coordinates. (i.e. if I have 20 nodes that i want to display in a single column: i need to take the range from, say 0.05 and 0.95 and divide it by 19). I need to do it separately for each "column".

I tried providing x coordinates without corresponding y coordinates in the hope that the algorithm will figure the rest out, but it simply ignored my x parameters.

Also, i came across domain_column parameter, but couldn't figure out how to use it as the documentation was scarce.

Please leave any suggestions that you may have. Thanks so much in advance!

p.s. Here's my code using x's and y's. Hoping to find a simpler, more elegant way:

import plotly.graph_objects as go
fig = go.Figure(go.Sankey(
    node = {
        "label": ["1a","1b", "2a", "2b", "3a", "3b", "4b"],
        "x": [0.05, 0.05, 0.35, 0.35, 0.65, 0.65, 0.95],
        "y": [0.25, 0.75, 0.25, 0.75, 0.70, 0.25, 0.7],
    link = {
        "source": [0, 1, 2, 3, 5, 3],
        "target": [3, 2, 4, 5, 6, 4],
        "value": [1, 1, 1, 1, 1, 1, 1]}))
#fig.update_traces(domain_column=8, selector=dict(type='sankey')) 
Back to Top