Revision: 8123 http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8123&view=rev Author: jdh2358 Date: 2010-02-10 15:56:34 +0000 (Wed, 10 Feb 2010)
Log Message: ----------- added Yannick Copin's sanke demo Added Paths: ----------- trunk/matplotlib/examples/api/sankey_demo.py Added: trunk/matplotlib/examples/api/sankey_demo.py =================================================================== --- trunk/matplotlib/examples/api/sankey_demo.py (rev 0) +++ trunk/matplotlib/examples/api/sankey_demo.py 2010-02-10 15:56:34 UTC (rev 8123) @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# Time-stamp: <2010-02-10 01:49:08 ycopin> + +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +from matplotlib.path import Path + +def sankey(ax, losses, labels=None, + dx=40, dy=10, angle=45, w=3, dip=10, offset=2, **kwargs): + """Draw a Sankey diagram. + + losses: array of losses, should sum up to 100% + labels: loss labels (same length as losses), + or None (use default labels) or '' (no labels) + dx: horizontal elongation + dy: vertical elongation + angle: arrow angle [deg] + w: arrow shoulder + dip: input dip + offset: text offset + **kwargs: propagated to Patch (e.g. fill=False) + + Return (patch,texts).""" + + assert sum(losses)==100, "Input losses don't sum up to 100%" + + def add_loss(loss, last=False): + h = (loss/2+w)*np.tan(angle/180.*np.pi) # Arrow tip height + move,(x,y) = path[-1] # Use last point as reference + if last: # Final loss (horizontal) + path.extend([(Path.LINETO,[x+dx,y]), + (Path.LINETO,[x+dx,y+w]), + (Path.LINETO,[x+dx+h,y-loss/2]), # Tip + (Path.LINETO,[x+dx,y-loss-w]), + (Path.LINETO,[x+dx,y-loss])]) + tips.append(path[-3][1]) + else: # Intermediate loss (vertical) + path.extend([(Path.LINETO,[x+dx/2,y]), + (Path.CURVE3,[x+dx,y]), + (Path.CURVE3,[x+dx,y+dy]), + (Path.LINETO,[x+dx-w,y+dy]), + (Path.LINETO,[x+dx+loss/2,y+dy+h]), # Tip + (Path.LINETO,[x+dx+loss+w,y+dy]), + (Path.LINETO,[x+dx+loss,y+dy]), + (Path.CURVE3,[x+dx+loss,y-loss]), + (Path.CURVE3,[x+dx/2+loss,y-loss])]) + tips.append(path[-5][1]) + + tips = [] # Arrow tip positions + path = [(Path.MOVETO,[0,100])] # 1st point + for i,loss in enumerate(losses): + add_loss(loss, last=(i==(len(losses)-1))) + path.extend([(Path.LINETO,[0,0]), + (Path.LINETO,[dip,50]), # Dip + (Path.CLOSEPOLY,[0,100])]) + codes,verts = zip(*path) + verts = np.array(verts) + + # Path patch + path = Path(verts,codes) + patch = mpatches.PathPatch(path, **kwargs) + ax.add_patch(patch) + + # Labels + if labels=='': # No labels + pass + elif labels is None: # Default labels + labels = [ '%2d%%' % loss for loss in losses ] + else: + assert len(labels)==len(losses) + + texts = [] + for i,label in enumerate(labels): + x,y = tips[i] # Label position + last = (i==(len(losses)-1)) + if last: + t = ax.text(x+offset,y,label, ha='left', va='center') + else: + t = ax.text(x,y+offset,label, ha='center', va='bottom') + texts.append(t) + + # Axes management + ax.set_xlim(verts[:,0].min()-10, verts[:,0].max()+40) + ax.set_ylim(verts[:,1].min()-10, verts[:,1].max()+20) + ax.set_aspect('equal', adjustable='datalim') + ax.set_xticks([]) + ax.set_yticks([]) + + return patch,texts + +if __name__=='__main__': + + losses = [10.,20.,5.,15.,10.,40.] + labels = ['First','Second','Third','Fourth','Fifth','Hurray!'] + labels = [ s+'\n%d%%' % l for l,s in zip(losses,labels) ] + + fig = plt.figure() + ax = fig.add_subplot(1,1,1) + + patch,texts = sankey(ax, losses, labels, fc='g', alpha=0.2) + texts[1].set_color('r') + texts[-1].set_fontweight('bold') + + plt.show() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev _______________________________________________ Matplotlib-checkins mailing list Matplotlib-checkins@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins