4

I want to plot some sankey diagrams representing mass flows of different substances for a report. I want to put a legend to differentiate the substances but I don't know how to do it. I've tried showlegend without success

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 = ['household','industry','waste'],
      color = "blue"
    ),
    link = dict(
      source = [0,1,0,1], # indices correspond to labels, eg A1, A2, A2, B1, ...
      target = [2,2,2,2],
      value = [7190,2074,4483,74.50],
      label = ['aluminium','aluminium','copper','copper'],
      color = ['#d7d6d6','#d7d6d6','#f3cf07','#f3cf07']
  ))])
fig.update_layout(showlegend=True)
fig.show() 

enter image description here

JohanC
  • 71,591
  • 8
  • 33
  • 66
Nabla
  • 1,509
  • 3
  • 20
  • 35

2 Answers2

5

It seems that Plotly Sankey traces don't actual support legends, despite the docs currently seeming to indicate they do.

I've created a corresponding issue on the Plotly repo; looks like the resolution may be improving the docs to make this clearer.

nedned
  • 3,552
  • 8
  • 38
  • 41
1

Still no official support, but you can work around it by:

  1. creating a dummy trace for each desired legend entry
  2. hide the axes and plot background
  3. display the legend
import plotly.graph_objects as go

colors = ["purple", "yellow", "yellow", "purple", "yellow", "yellow"]

sankey = go.Sankey(
    node=dict(color="blue"),
    link=dict(
        source=[0, 1, 0, 2, 3, 3],
        target=[2, 3, 3, 4, 4, 5],
        value=[8, 4, 2, 8, 4, 2],
        color=colors,
    ),
)

legend = []
legend_entries = [
    ["purple", "My Legend Text 1"],
    ["yellow", "My Legend Text 2"],
]
for entry in legend_entries:
    legend.append(
        go.Scatter(
            mode="markers",
            x=[None],
            y=[None],
            marker=dict(size=10, color=entry[0], symbol="square"),
            name=entry[1],
        )
    )

traces = [sankey] + legend
layout = go.Layout(
    showlegend=True,
    plot_bgcolor="rgba(0,0,0,0)",
)

fig = go.Figure(data=traces, layout=layout)
fig.update_xaxes(visible=False)
fig.update_yaxes(visible=False)
fig.show()

Which should give you this: sankey+legend

EmRa
  • 11
  • 3
  • Hi! Would you mind completing your code so that it works as a standalone snippet? Users would benefit of that, especially given the apparently stale issue on GitHub. – Maciej Skorski May 11 '23 at 05:11
  • Sorry - was in a rush when I posted this, updated now to show a more complete example. – EmRa May 17 '23 at 17:58
  • thanks for your contribution. I think we can still add labels, e.g. household, industry and so on? – Maciej Skorski May 18 '23 at 06:26