Connecting two Sankey diagrams in matplotlib
Asked Answered
T

1

1

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?

Turntable answered 6/12, 2013 at 13:27 Comment(2)
With a more recent version, I the proper error message is AssertionError: The connection index to the source diagram is 3, but that diagram has only 2 flows. The index is zero-based.Osteo
Thanks, tiago!! That's interesting because the diagram has 4 flows. 3 inflows and one outflow. And thanks for letting me know that my version is not the latest. I'm very new to Python and though that easy_install automatically installs the latest version. Apparently not.Turntable
O
2

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

Osteo answered 6/12, 2013 at 14:35 Comment(1)
Great! Thanks! I solved my problem different way... I removed patchlabel="Gas balance" and it worked. Probably some weird bug! Your version works even without removing patch label.Turntable

© 2022 - 2024 — McMap. All rights reserved.