Plotly: how to write a text over my Sankey diagram columns?
Asked Answered
U

2

8

I've build a Sankey diagram using plotly. I want to name the columns giving each one a column title, like the text in red below:

here is where I want to put the columns

How can I write these column titles?

Urbano answered 14/5, 2021 at 21:6 Comment(0)
P
8

You can use annotations to add text, using x-values of 0, 1, 2 with the xref set to "x", and using y-values of 1.05 with the yref set to "paper" as in paper coordinates. This will ensure the annotations are above the plot.

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]
  ))])

layout={
      
     }

for x_coordinate, column_name in enumerate(["column 1","column 2","column 3"]):
  fig.add_annotation(
          x=x_coordinate,
          y=1.05,
          xref="x",
          yref="paper",
          text=column_name,
          showarrow=False,
          font=dict(
              family="Courier New, monospace",
              size=16,
              color="tomato"
              ),
          align="center",
          )

fig.update_layout(
  title_text="Basic Sankey Diagram", 
  xaxis={
  'showgrid': False, # thin lines in the background
  'zeroline': False, # thick line at x=0
  'visible': False,  # numbers below
  },
  yaxis={
  'showgrid': False, # thin lines in the background
  'zeroline': False, # thick line at x=0
  'visible': False,  # numbers below
  }, plot_bgcolor='rgba(0,0,0,0)', font_size=10)

fig.show()

Sankey with titles

Papyraceous answered 14/5, 2021 at 23:15 Comment(4)
Nice! The code wrote the columns perfectly, but it generated a grid and axes in the diagram.Urbano
I solved the problem adding this to my figure: layout={ 'xaxis': { 'showgrid': False, # thin lines in the background 'zeroline': False, # thick line at x=0 'visible': False, # numbers below }, 'yaxis': { 'showgrid': False, # thin lines in the background 'zeroline': False, # thick line at x=0 'visible': False, # numbers below }, 'plot_bgcolor':'rgba(0,0,0,0)', }Urbano
Ah I see - it looks like a grid and axes are generated by default if x-coordinates are referenced in an annotation, but modifying the layout is a sensible solution. I am glad my answer was helpful!Papyraceous
I've included the layout configuration to your answer to make it better.Urbano
L
3

It seems like you might actually prefer a parcats diagram instead of a sankey diagram. But if you really want to do this with sankey, a slight modification of Derek O's answer avoids generating the axes you then need to hide. Just use xref="paper" and distribute the x values in the range 0 to 1:

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]
  ))])

cols = ["column 1","column 2","column 3"]
for x_coordinate, column_name in enumerate(cols):
  fig.add_annotation(
          x=x_coordinate / (len(cols) - 1),
          y=1.05,
          xref="paper",
          yref="paper",
          text=column_name,
          showarrow=False,
          font=dict(
              family="Courier New, monospace",
              size=16,
              color="tomato"
              ),
          align="center",
          )

fig.show()
License answered 23/5, 2022 at 21:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.