Add node count to Plotly Sankey diagram
Asked Answered
M

1

6

I would like to add node count to each node in a Plotly Sankey diagram (https://plot.ly/python/sankey-diagram/) to look like the count referenced by red arrows. enter image description here

Is this possible? I cannot find example of this in plotly. The example, I provided above is from a library in R (https://github.com/fbreitwieser/sankeyD3/blob/master/README.md) but I'm using plotly in Python.

Below is my code.

import plotly.graph_objects as go
import pandas as pd

def plot_sankey(df, title):
    # Get column names
    cat_columns = [key for key, value in df.dtypes.iteritems() if value == 'O']

    # Mapping to unique values for categorical columns
    labels = pd.unique(df[cat_columns].values.ravel('K')).tolist()

    # Break dowmn each step
    final = []
    for i, row in df.iterrows():
        cat_values = row[cat_columns].values
        value = row['value']
        final.extend([(a, b, value) for a, b in zip(cat_values, cat_values[1:]) if a!=None and b!=None])

    # Build formatted version
    df_formatted = pd.DataFrame(final, columns=['source', 'target', 'value'])


    # Build Node
    node = dict(
              pad = 15,
              thickness = 20,
              line = dict(color = "black", width = 0.5),
              label = labels,
              color = "blue"
            )

    # Build Link
    link = dict(
              source = [labels.index(x) for x in df_formatted['source'].tolist()],
              target = [labels.index(x) for x in df_formatted['target'].tolist()],
              value = df_formatted['value'].tolist()
          )

    # Plot
    fig = go.Figure(data=[go.Sankey(node=node, link=link, visible=True)])
    fig.update_layout(title_text=title, 
                      font_size=10,
                      autosize=False,
                      width=2750,
                      height=1600)
    fig.show()
Madrepore answered 29/1, 2020 at 21:9 Comment(0)
D
6

It doesn't seem like it is possible directly. However, anything you provide through

node = dict( label = ["A1", "A2", "B1", "B2", "C1"])

will be displayed on the plot.

Assuming you can calculate the totals per node beforehand, you can pass a string for each node with name and value like so:

label = ["{} {}".format(node1_name, node1_val), "{} {}".format(node2_name, node2_val) ...]

Alternatively, you can do it in the hover. See here.

The plotly sunburst allows you to nicely do this through the "textinfo" property where you can just pass "label+value" - but this is not available in sankey as of plotly 4.9 docs.

Durrell answered 2/9, 2020 at 17:5 Comment(1)
But how can we calculate node count?Boreal

© 2022 - 2024 — McMap. All rights reserved.