Quickstart

Installation

You can get the latest version with

pip install --upgrade --no-deps git+https://github.com/j-i-l/pyalluv.git

Examples

Life-cycle events of a dynamic cluster

_images/life_cycles.png

Life-cycle events of a dynamic community. Derived from Fig.1 of https://arxiv.org/abs/1912.04261.

from copy import deepcopy
from matplotlib import pyplot as plt
import matplotlib.gridspec as gridspec

from pyalluv import AlluvialPlot, Cluster, Flux

# Create the sequence of clusterings
time_points = [0, 4, 9, 14, 18.2]
# Define the cluster sizes per snapshot
# at each time point {cluster_id: cluster_size})
cluster_sizes = [{0: 3}, {0: 5}, {0: 3, 1: 2}, {0: 5}, {0: 4}]
# Define the membership fluxes between neighbouring clusterings
between_fluxes = [
        {(0, 0): 3},  # key: (from cluster, to cluster), value: size
        {(0, 0): 3, (0, 1): 2},
        {(0, 0): 3, (1, 0): 2},
        {(0, 0): 4}
        ]

# set the colors
cluster_color = {0: "C1", 1: "C2"}
# create a dictionary with the time points as keys and a list of clusters
# as values
clustering_sequence = {}
for tp, clustering in enumerate(cluster_sizes):
    clustering_sequence[time_points[tp]] = [
            Cluster(
                height=clustering[cid],
                label="{0}".format(cid),
                facecolor=cluster_color[cid],
                ) for cid in clustering
            ]
# now create the fluxes between the clusters
for tidx, tp in enumerate(time_points[1:]):
    fluxes = between_fluxes[tidx]
    for from_csid, to_csid in fluxes:
        Flux(
            flux=fluxes[(from_csid, to_csid)],
            source_cluster=clustering_sequence[time_points[tidx]][from_csid],
            target_cluster=clustering_sequence[tp][to_csid],
            facecolor='source_cluster'
            )

# #############################################################################
# Create the figure
# #############################################################################
# with plt.xkcd():
if True:
    fig1 = plt.figure(figsize=(6, 4.2))
    gsCom = gridspec.GridSpec(
        9, 16,
        left=0.05, wspace=2.0, hspace=2.0, top=0.99, bottom=0.07, right=0.95
    )
    # #############################################################################
    # The sankey illustration part

    alluvial_plot_params = {
            'x_axis_offset': 0.00,
            'redistribute_vertically': 10,
            'with_cluster_labels': False,
            }
    ax_sk = fig1.add_subplot(gsCom[2:9, :],)
    ax_sk.axis('equal')
    ax_sk.set_xlim(0, 25)
    ax_sk.set_ylim(-0.6, 3)
    AlluvialPlot(clustering_sequence, ax_sk, **alluvial_plot_params)
    ax_sk.set_xticks(time_points, minor=False)
    ax_sk.set_xticklabels(
        [
            r'$\mathbf{{t_{0}}}$'.format(idx)
            for idx in range(6)
            ],
        minor=False,
        size=9
        )
    ax_sk.tick_params(axis=u'x', which=u'both', length=0)

    # #########################################################################
    # Annotation part

The full script can be downloaded here.