Search code examples
pythonpython-3.xplotlyplotly-pythonsankey-diagram

Remove text labels in Plotly Sankey diagram, but keep the data when hovering [Plotly Python Sankey question]


I want to keep the labels when you hover, but hide the labels from just appearing over the Sankey as text.

Here is my code:

labels = df_mapping['Name'].to_numpy().tolist() + labels
count_dict = {}
source = []
target = []
value = df_subset['Stuff'].to_numpy().tolist()
index = 0
for x in unique_broad:
    count_dict[x] = len(df_mapping.loc[df_mapping['Stuff'] == x])
for key in count_dict:
    for i in range(count_dict[key]):
        source.append(index)
        index += 1
for key in count_dict:
    for i in range(count_dict[key]):
        target.append(index)
    index += 1
number_of_colors = len(source)
color_link = ["#"+''.join([random.choice('0123456789ABCDEF') for j in range(6)])
             for i in range(number_of_colors)]
link = dict(source=source, target=target, value=value, color=color_link)
node = dict(label=labels, pad=35, thickness=10)
data = go.Sankey(link=link, node=node)
fig = go.Figure(data)
fig.update_layout(
    hovermode = 'x',
    title="Sankey for Stuff",
    font=dict(size=8, color='white'),
    paper_bgcolor='#51504f'
)
return fig

Picture of what needs to change


Solution

  • You can make the labels invisible by setting the color of the labels to rgba(0,0,0,0). This ensures that the label will remain in the hovertemplate, but not show up on the nodes.

    To do this you can pass textfont=dict(color="rgba(0,0,0,0)", size=1) to go.Sankey such as in the example you used from the Plotly sankey diagram documentation:

    import plotly.graph_objects as go
    import urllib.request, json
    
    url = 'https://raw.githubusercontent.com/plotly/plotly.js/master/test/image/mocks/sankey_energy.json'
    response = urllib.request.urlopen(url)
    data = json.loads(response.read())
    
    # override gray link colors with 'source' colors
    opacity = 0.4
    # change 'magenta' to its 'rgba' value to add opacity
    data['data'][0]['node']['color'] = ['rgba(255,0,255, 0.8)' if color == "magenta" else color for color in data['data'][0]['node']['color']]
    data['data'][0]['link']['color'] = [data['data'][0]['node']['color'][src].replace("0.8", str(opacity))
                                        for src in data['data'][0]['link']['source']]
    
    fig = go.Figure(data=[go.Sankey(
        textfont=dict(color="rgba(0,0,0,0)", size=1),
        valueformat = ".0f",
        valuesuffix = "TWh",
        # Define nodes
        node = dict(
          pad = 15,
          thickness = 15,
          line = dict(color = "black", width = 0.5),
          label =  data['data'][0]['node']['label'],
          color =  data['data'][0]['node']['color']
        ),
        # Add links
        link = dict(
          source =  data['data'][0]['link']['source'],
          target =  data['data'][0]['link']['target'],
          value =  data['data'][0]['link']['value'],
          label =  data['data'][0]['link']['label'],
          color =  data['data'][0]['link']['color']
    ))])
    
    fig.update_layout(title_text="Energy forecast for 2050<br>Source: Department of Energy & Climate Change, Tom Counsell via <a href='https://bost.ocks.org/mike/sankey/'>Mike Bostock</a>",
                      font_size=10)
    fig.show()
    

    You get the following:

    enter image description here