nazca
nazca

Reputation: 350

Sankey diagrams in Python

Is there a Python library for generating Sankey diagrams?

I've seen this list of Sankey diagram applications and libraries, but none of them is in Python.

Upvotes: 15

Views: 12496

Answers (6)

import pandas as pd
import holoviews as hv
import hvplot.pandas

# Enable the Bokeh backend
hv.extension('bokeh')

# Define your data
data = {
    'source': ["UAE Cards TTD", "UAE Cards TTD", "CREDIT STP", "CREDIT STP", "CREDIT STP", "APPROVED STP", "MANUAL", "MANUAL", "APPROVED MANUAL", "APPROVED MANUAL"],
    'target': ["CREDIT STP", "MANUAL", "DROP-OFF", "DECLINE STP", "APPROVED STP", "NOTUSED STP", "DECLINE", "APPROVED MANUAL", "NOTUSED MANUAL", "USED MANUAL"],
    'value': [217416, 71684, 116747, 80453, 25416, 7110, 18306, 21097, 12553, 33080]
}

# Create a DataFrame
df = pd.DataFrame(data)

# Create the Sankey diagram
sankey = df.hvplot.sankey(label='Sankey Diagram for your data', width=800, height=600)

# Show the plot
hv.save(sankey, 'sankey.html')
sankey

Upvotes: 0

rileyx
rileyx

Reputation: 412

Other answers have provided many good options. However I wanted something that works with Matplotlib, but looked more like the diagrams you get from sankeymatic.

I found pySankey, but it only allows for 1 level of bijective flow.

I ended writing a package SankeyFlow. This uses purely Matplotlib and produces flows like below.

sankeyflow example

from sankeyflow import Sankey
import matplotlib.pyplot as plt

plt.figure(figsize=(20, 10), dpi=144)

flows = [
    ('Product', 'Total revenue', 20779),
    ('Sevice\nand other', 'Total revenue', 30949),
    ('Total revenue', 'Gross margin', 34768),
    ('Total revenue', 'Cost of revenue', 16960),
    ('Gross margin', 'Operating income', 22247),
    ('Operating income', 'Income before\nincome taxes', 22247, {'flow_color_mode': 'dest'}),
    ('Other income, net', 'Income before\nincome taxes', 268),
    ('Gross margin', 'Research and\ndevelopment', 5758), 
    ('Gross margin', 'Sales and marketing', 5379), 
    ('Gross margin', 'General and\nadministrative', 1384),
    ('Income before\nincome taxes', 'Net income', 18765), 
    ('Income before\nincome taxes', 'Provision for\nincome taxes', 3750),
]

s = Sankey(flows=flows, flow_color_mode='lesser')
s.draw()
plt.show()

Upvotes: 1

Sri Test
Sri Test

Reputation: 387

You can use sankey diagram from plotly dash.

A basic illustrative example, adapted from the link above:

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 = "green"
    ),
    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 = [7, 5, 3, 9, 5, 3]
  ))])

fig.update_layout(title_text="Simple Sankey Diagram using plotly in Python.", font_size=10)
fig.show()

Upvotes: 3

ricklupton
ricklupton

Reputation: 354

In my research group we use Sankey diagrams from Python inside Jupyter notebooks, using open-source projects (note: I'm the developer of these projects) to embed D3/SVG-based Sankey in the output.

  • floWeaver provides more structure to the data aggregation that's often involved in drawing a Sankey diagram,
  • ipysankeywidget just draws the Sankey diagram.

Both of these are based on a d3 library, d3-sankey-diagram which adds some features to the standard d3 sankey plugin (loops, multiple flow types, more control over layout).

Upvotes: 2

saveenr
saveenr

Reputation: 8619

Apparently matplotlib 1.1 can now do this. Code and sample output is here.

Below is a screenshot demonstrating what it can do.

enter image description here

Upvotes: 10

steveha
steveha

Reputation: 76715

I did a Google search on "Python graph visualization" and found some stuff. There are several libraries that have "spring" behavior where the software balances out a graph and makes it pretty; they do much of the work for you. But they draw graph diagrams, with nodes and edges, nothing like a Sankey diagram.

A Google search on "Python sankey" produced no useful results.

I did some Google searches on "Python vector graphics" and found this very promising result:

http://pypi.python.org/pypi/Things

With Things, apparently you draw basic shapes in Inkscape (a free vector editing program) and then you write Python to scale, rotate, etc. the shapes to produce an image or an animation. It should be possible to write Python code to automatically make the Sankey arrows spring away from their sources, turning up, down, whatever.

See also the StackOverflow discussion of drawing vector diagrams in Python: svg diagrams using python

That page led me to: http://cairographics.org/ which looks very useful.

The blog you linked has a posting about an article on automatic Sankey diagram creation:

http://www.sankey-diagrams.com/sankey-diagrams-are-directed-weighted-graphs/

http://www.svgopen.org/2003/papers/RenderingGraphs/index.html

I didn't find a turnkey solution for you, but I did find some parts that could potentially be used in a solution. Good luck.

Upvotes: 2

Related Questions