I am encountering frustrating layout or plot dimension issues when creating a vertical flow chart with Plotly's Sankey figure. Parts of the chart get cut-off like so:
The core of the problem appears to be the use of defined node positions in conjunction with orientation = "v"
. When changing the domain
x and y parameters of the figure to [0.5,1], the entire charts gets visible, but the layout is terrible, and surely so is the fix. My question is:
How can you draw a vertical Sankey chart with defined node positions?
The problem is easily reproduced by changing the Sankey example given on Plotly's website:
Horizontal Sankey chart with defined node positions
import plotly.graph_objects as go
fig = go.Figure(go.Sankey(
arrangement = "snap",
node = {
"label": ["A", "B", "C", "D", "E", "F"],
"x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],
"y": [0.7, 0.5, 0.2, 0.4, 0.2, 0.3],
'pad':10}, # 10 Pixels
link = {
"source": [0, 0, 1, 2, 5, 4, 3, 5],
"target": [5, 3, 4, 3, 0, 2, 2, 3],
"value": [1, 2, 1, 1, 1, 1, 1, 2]}))
fig.show()
This produces the example. When changing the orientation
parameter (default is "h") of Sankey's figure reference, the charts gets cut-off.
Vertical Sankey chart with defined node positions
import plotly.graph_objects as go
fig = go.Figure(go.Sankey(
orientation = "v",
arrangement = "snap",
node = {
"label": ["A", "B", "C", "D", "E", "F"],
"x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],
"y": [0.7, 0.5, 0.2, 0.4, 0.2, 0.3],
'pad':10}, # 10 Pixels
link = {
"source": [0, 0, 1, 2, 5, 4, 3, 5],
"target": [5, 3, 4, 3, 0, 2, 2, 3],
"value": [1, 2, 1, 1, 1, 1, 1, 2]}))
fig.show()
When removing the x and y parameters of the figure's node configuration, the chart no longer gets cut-off, but the order is lost.
Vertical Sankey chart without defined node positions
import plotly.graph_objects as go
fig = go.Figure(go.Sankey(
orientation = "v",
arrangement = "snap",
node = {
"label": ["A", "B", "C", "D", "E", "F"],
# "x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],
# "y": [0.7, 0.5, 0.2, 0.4, 0.2, 0.3],
'pad':10}, # 10 Pixels
link = {
"source": [0, 0, 1, 2, 5, 4, 3, 5],
"target": [5, 3, 4, 3, 0, 2, 2, 3],
"value": [1, 2, 1, 1, 1, 1, 1, 2]}))
fig.show()
Lastly, by changing the figure's domain values for x and y, the entire chart is visible, but I doubt that this will hold for more data and be useful building a Dash app.
Quick fix
import plotly.graph_objects as go
fig = go.Figure(go.Sankey(
domain = dict(
x = [0.5,1],
y = [0.5,1]
),
orientation = "v",
arrangement = "snap",
node = {
"label": ["A", "B", "C", "D", "E", "F"],
"x": [0.2, 0.1, 0.5, 0.7, 0.3, 0.5],
"y": [0.7, 0.5, 0.2, 0.4, 0.2, 0.3],
'pad':10}, # 10 Pixels
link = {
"source": [0, 0, 1, 2, 5, 4, 3, 5],
"target": [5, 3, 4, 3, 0, 2, 2, 3],
"value": [1, 2, 1, 1, 1, 1, 1, 2]}))
fig.show()