Colorscales for Sankey diagram not displaying

Hi all. I would like to apply a colorscale for the links in a Sankey diagram so that the first link is yellow, the very last link is blue, and all links in-between are defined by the colorscale 'YlGnBl'. Here is my code:

import plotly.graph_objects as go  

fig = go.Figure(go.Sankey( 
    arrangement = "snap",
    node = {
        "label": names,
        'pad':10,
        'color':'lightgray'
    },  
    link = {
        "source": sources,
        "target": targets,
        "value": values, 
        'colorscales' : [{'colorscale':'YlGnBu'}] 
    })) 
fig.show()

The Sankey diagram itself shows as intended (and no errors are raised), but all links are displayed in the standard light gray color. What is it that goes wrong? I am using Plotly 4.5.3 with Python 3.7.4.
Thanks for helping.

Hi @anne-agathe, welcome to the forum! I’m not sure I understand how sankey colorscales work to be honest, but the only way I found to change the color of links was to use label attributes for the links, as in the example below

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, A2, B1, ...
      target = [2, 3, 3, 4, 4, 5],
      value = [8, 4, 2, 8, 4, 2],
      label = ["A","B",] * 3,
      colorscales=[{'label': "A", 'colorscale':'RdBu'}, {'label': "B", 'colorscale':'Greens'}]
  ))])

fig.update_layout(title_text="Basic Sankey Diagram", font_size=10)
fig.show()

But I’m not sure you should use colorscales here, instead you can define one color per link as follows

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, A2, B1, ...
      target = [2, 3, 3, 4, 4, 5],
      value = [8, 4, 2, 8, 4, 2],
      color=['red', 'blue', 'red', 'yellow', 'green', 'blue'],
  ))])

fig.update_layout(title_text="Basic Sankey Diagram", font_size=10)
fig.show()


Hope this helps a little.

Hey, I wonder if we are running into the same problem and whether you managed to fix it. My problem is that I have an unspecified number of links (using the Sankey diagram in dash where the user can filter the data first). So, I would like the colorscale to pick colors for all integers in an interval. The documentation states the following for the colorscale key in dict colorscales:

“Sets the colorscale. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, [[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]. To control the bounds of the colorscale in color space, usecmin and cmax. Alternatively, colorscale may be a palette name string of the following list: Greys,YlGnBu,Greens,YlOrRd,Bluered,RdBu,Reds,Blues,Picnic,Rainbow,Portland,Jet,Hot,Blackbody,Earth,Electric,Viridis,Cividis.”

My guess is that the ‘alternative’ case of colorscale being a palette name string applies to the case I want. So, bounds cmin and cmax also need to be defined in the dict colorscales. I tested this for a manual input of range 0 to 4 and with the input I want to give. Here follows my code (hope the format works, first time posting). uniq_edges is a pandas dataframe with my unique edges.
Colors are just the gray transparent colors indeed. I originally thought it might go wrong in the updating of traces, because it does not raise an error. But that does not seem to be the case. Does anybody have an solution?

`link=dict(
label = uniq_edges[‘sTime’], # First time link occurs
source=uniq_edges[‘loc_s’], # Source node index
target=uniq_edges[‘loc_t’], # Target node index
value = uniq_edges[‘count’], # Volume of link
colorscales =[{‘cmin’: 0, ‘cmax’: uniq_edges[‘count’].max(), ‘colorscale’: ‘YlGnBu’}],

 )`