'plotly sankey diagram positioning
I'd like to add some annotations to Plotly Sankey diagram.
And I want to draw them right over the blocks of sankey nodes (with the same x-position)
but couldn't find the way to do it, or even to find the X coordinates of nodes. (Think it would be better to get them and not to add manually, because number of sankey levels could change)
If we'll take this basic example, I want to add "A" "B" and "C" labels over corresponding nodes
import plotly.graph_objects as go
fig = go.Figure(data=[go.Sankey(
node = dict(
pad = 15,
thickness = 20,
line = dict(color = "black", width = 0.5),
label = ["A1", "A2", "B1", "B2", "C1", "C2"],
color = "blue"
),
link = dict(
source = [0, 1, 0, 2, 3, 3], # indices correspond to labels, eg A1, A2, A1, B1, ...
target = [2, 3, 3, 4, 4, 5],
value = [8, 4, 2, 8, 4, 2]
))])
fig.update_layout(title_text="Basic Sankey Diagram", font_size=10)
fig.show()
Solution 1:[1]
You can use fig.add_annotation()
in this case. Add the following lines below line with fig.update_layout()
fig.add_annotation(dict(font=dict(color="black",size=12), x=0, y=1.06, showarrow=False, text='<b>A</b>'))
fig.add_annotation(dict(font=dict(color="black",size=12), x=0.5, y=1.06, showarrow=False, text='<b>B</b>'))
fig.add_annotation(dict(font=dict(color="black",size=12), x=1, y=1.06, showarrow=False, text='<b>C</b>'))
You will get the figure as follows. You can modify the code depending on your requirement.
Solution 2:[2]
Here's an unnecessary expansion of a previous answer.
If we start with the basic diagram:
import plotly.graph_objects as go
fig = go.Figure(data=[go.Sankey(
node = dict(
pad = 15,
thickness = 20,
line = dict(color = "black", width = 0.5),
label = ["A1", "A2", "B1", "B2", "C1", "C2"],
color = "blue"
),
link = dict(
source = [0, 1, 0, 2, 3, 3], # indices correspond to labels, eg A1, A2, A1, B1, ...
target = [2, 3, 3, 4, 4, 5],
value = [8, 4, 2, 8, 4, 2]
))])
fig.write_image("fig1.png")
fig.show()
Then add annotations. If we don't specify the location it will be in the middle of the plot.
fig.add_annotation(text='<b>DEFAULT</b>',font_color="red") # unspecified position
We can specify locations using x,y coordinates:
fig.add_annotation(x=0, y=0, text='<b>(0,0)</b>', font_color="red")
fig.add_annotation(x=1, y=1, text='<b>(1,1)</b>', font_color="red")
Now that we know the layout we can put the desired labels into a list and use that to position them automatically as follows:
lab_list = ['<b>A</b>','<b>B</b>','<b>C</b>']
for i, text in enumerate(lab_list):
x_val = i / (len(lab_list)-1)
fig.add_annotation(
x=x_val,
y=1.06,
text=text,
showarrow=False
)
Now fig.show()
yields the plot with the properly positioned annotations.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | hbstha123 |
Solution 2 | Arthur Morris |