Connecting two Sankey diagrams in matplotlib

2.9k views Asked by At

I'm trying to represent a country's gas balance using matplotlib.

The idea is that there are three sources of imported gas which I want to plot using one Sankey and connect it to another Sankey which has other sources of gas (production, gas storages) and gas consumers as outflows.

I tried it many times but I cannot connect two graphs together.

Each of the graphs separately plots as designed. But as soon as I add "prior=0, connect=(3,0)" which supposedly connects two graphs together everything goes awry giving me errors which I cannot fully understand. Here is the code.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.sankey import Sankey


ImportLabels=["Imports by\nNaftogaz","Imports by\nOstchem","Imports from\nEurope", ""]
ImportFlows=[11.493,9.768,1.935,-23.196]
ImportOrientation=[0,1,-1,0]

l=["Imports","Private\nextraction","State\nextraction","Net supplies\ntoUGS","Households","TKE","Metallurgy","Energy","Other\nIndustries","Technological\nlosses"]
v=[23.196,3.968,13.998,-2.252,-13.289,-7.163,-3.487,-4.72,-7.037,-3.17]
d=[0,-1,1,-1,0,0,1,1,1,-1]

sankey=Sankey(scale=1.0/69,patchlabel="Gas balance",format='%.1f',margin=0.15)
sankey.add(flows=ImportFlows, labels=ImportLabels, orientations=ImportOrientation, label='Imports',fc='#00AF00')
sankey.add(flows=v,labels=l,orientations=d, prior=0, connect=(3,0),label='Second',fc='#008000')

The idea is to connect 3 outflow from first graph (which has -23.196 value) with 0 inflow of the second sankey (which also has 23.196)

And here is the error text:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-1220fede42ce> in <module>()
     14 sankey=Sankey(scale=1.0/69,patchlabel="Gas balance",format='%.1f',margin=0.15)
     15 sankey.add(flows=ImportFlows, labels=ImportLabels,  orientations=ImportOrientation, label='Imports',fc='#00AF00')
---> 16 sankey.add(flows=v,labels=l,orientations=d, prior=0, connect=(3,0),label='Second',fc='#008000')

C:\Python27\lib\site-packages\matplotlib\sankey.pyc in add(self, patchlabel, flows, orientations, labels, trunklength, pathlengths, prior, connect, rotation, **kwargs)
    369                    ("The connection index to the source diagram is %d, but "
    370                     "that diagram has only %d flows.\nThe index is zero-based."
--> 371                     % connect[0], len(self.diagrams[prior].flows))
    372             assert connect[1] < n, ("The connection index to this diagram is "
    373                                     "%d, but this diagram has only %d flows.\n"

TypeError: not enough arguments for format string

So I'm not sure Is it problem with connection between two graphs (suggested by the text the sankey.pyc is trying to display) or is it something wrong with matplotlib itself as "TypeError: not enough arguments for format string" indicates?

1

There are 1 answers

1
tiago On BEST ANSWER

Your problem is that you're putting two .add() calls. The first call to Sankey() already builds one diagram (default gray, with 1 inflow and 1 outflow). So when you try to connect to the first diagram, it fails because it has only one flow, and you're trying to connect to the third flow. (It would fail anyway because the flows don't match.)

You need to set up your first diagram in the first call and have only one add call, e.g.:

sankey = Sankey(scale=1.0/69,patchlabel="Gas balance",format='%.1f',margin=0.15,
                flows=ImportFlows, labels=ImportLabels, 
                orientations=ImportOrientation, label='Imports',fc='#00AF00')
sankey.add(flows=v,labels=l,orientations=d, label='Second',fc='#008000', prior=0,
           connect=(3, 0))

This gives me: enter image description here