@@ -62,6 +62,129 @@ class Sankey:
6262 `Wikipedia (6/1/2011) <http://en.wikipedia.org/wiki/Sankey_diagram>`_
6363
6464 """
65+
66+ def __init__ (self , ax = None , scale = 1.0 , unit = '' , format = '%G' , gap = 0.25 ,
67+ radius = 0.1 , shoulder = 0.03 , offset = 0.15 , head_angle = 100 ,
68+ margin = 0.4 , tolerance = 1e-6 , ** kwargs ):
69+ """
70+ Create a new Sankey instance.
71+
72+ Optional keyword arguments:
73+
74+ =============== ===================================================
75+ Field Description
76+ =============== ===================================================
77+ *ax* axes onto which the data should be plotted
78+ If *ax* isn't provided, new axes will be created.
79+ *scale* scaling factor for the flows
80+ *scale* sizes the width of the paths in order to
81+ maintain proper layout. The same scale is applied
82+ to all subdiagrams. The value should be chosen
83+ such that the product of the scale and the sum of
84+ the inputs is approximately 1.0 (and the product of
85+ the scale and the sum of the outputs is
86+ approximately -1.0).
87+ *unit* string representing the physical unit associated
88+ with the flow quantities
89+ If *unit* is None, then none of the quantities are
90+ labeled.
91+ *format* a Python number formatting string to be used in
92+ labeling the flow as a quantity (i.e., a number
93+ times a unit, where the unit is given)
94+ *gap* space between paths that break in/break away
95+ to/from the top or bottom
96+ *radius* inner radius of the vertical paths
97+ *shoulder* size of the shoulders of output arrowS
98+ *offset* text offset (from the dip or tip of the arrow)
99+ *head_angle* angle of the arrow heads (and negative of the angle
100+ of the tails) [deg]
101+ *margin* minimum space between Sankey outlines and the edge
102+ of the plot area
103+ *tolerance* acceptable maximum of the magnitude of the sum of
104+ flows
105+ The magnitude of the sum of connected flows cannot
106+ be greater than *tolerance*.
107+ =============== ===================================================
108+
109+ The optional arguments listed above are applied to all subdiagrams so
110+ that there is consistent alignment and formatting.
111+
112+ If :class:`Sankey` is instantiated with any keyword arguments other
113+ than those explicitly listed above (``**kwargs``), they will be passed
114+ to :meth:`add`, which will create the first subdiagram.
115+
116+ In order to draw a complex Sankey diagram, create an instance of
117+ :class:`Sankey` by calling it without any kwargs::
118+
119+ sankey = Sankey()
120+
121+ Then add simple Sankey sub-diagrams::
122+
123+ sankey.add() # 1
124+ sankey.add() # 2
125+ #...
126+ sankey.add() # n
127+
128+ Finally, create the full diagram::
129+
130+ sankey.finish()
131+
132+ Or, instead, simply daisy-chain those calls::
133+
134+ Sankey().add().add... .add().finish()
135+
136+ .. seealso::
137+
138+ :meth:`add`
139+ :meth:`finish`
140+
141+
142+ **Examples:**
143+
144+ .. plot:: mpl_examples/api/sankey_demo_basics.py
145+ """
146+ # Check the arguments.
147+ assert gap >= 0 , (
148+ "The gap is negative.\n This isn't allowed because it "
149+ "would cause the paths to overlap." )
150+ assert radius <= gap , (
151+ "The inner radius is greater than the path spacing.\n "
152+ "This isn't allowed because it would cause the paths to overlap." )
153+ assert head_angle >= 0 , (
154+ "The angle is negative.\n This isn't allowed "
155+ "because it would cause inputs to look like "
156+ "outputs and vice versa." )
157+ assert tolerance >= 0 , (
158+ "The tolerance is negative.\n It must be a magnitude." )
159+
160+ # Create axes if necessary.
161+ if ax is None :
162+ import matplotlib .pyplot as plt
163+ fig = plt .figure ()
164+ ax = fig .add_subplot (1 , 1 , 1 , xticks = [], yticks = [])
165+
166+ self .diagrams = []
167+
168+ # Store the inputs.
169+ self .ax = ax
170+ self .unit = unit
171+ self .format = format
172+ self .scale = scale
173+ self .gap = gap
174+ self .radius = radius
175+ self .shoulder = shoulder
176+ self .offset = offset
177+ self .margin = margin
178+ self .pitch = np .tan (np .pi * (1 - head_angle / 180.0 ) / 2.0 )
179+ self .tolerance = tolerance
180+
181+ # Initialize the vertices of tight box around the diagram(s).
182+ self .extent = np .array ((np .inf , - np .inf , np .inf , - np .inf ))
183+
184+ # If there are any kwargs, create the first subdiagram.
185+ if len (kwargs ):
186+ self .add (** kwargs )
187+
65188 def _arc (self , quadrant = 0 , cw = True , radius = 1 , center = (0 , 0 )):
66189 """
67190 Return the codes and vertices for a rotated, scaled, and translated
@@ -558,7 +681,7 @@ def add(self, patchlabel='', flows=None, orientations=None, labels='',
558681 llpath [- 1 ][1 ][1 ]]))
559682 has_left_input = True
560683 tip , label_location = self ._add_input (llpath , angle , * spec )
561- tips [n - i - 1 , :], = tip
684+ tips [n - i - 1 , :] = tip
562685 label_locations [n - i - 1 , :] = label_location
563686 # Add the right-side outputs from the top downwards.
564687 has_right_output = False
@@ -722,124 +845,4 @@ def finish(self):
722845 self .ax .set_aspect ('equal' , adjustable = 'datalim' )
723846 return self .diagrams
724847
725- def __init__ (self , ax = None , scale = 1.0 , unit = '' , format = '%G' , gap = 0.25 ,
726- radius = 0.1 , shoulder = 0.03 , offset = 0.15 , head_angle = 100 ,
727- margin = 0.4 , tolerance = 1e-6 , ** kwargs ):
728- """
729- Create a new Sankey instance.
730-
731- Optional keyword arguments:
732-
733- =============== ===================================================
734- Field Description
735- =============== ===================================================
736- *ax* axes onto which the data should be plotted
737- If *ax* isn't provided, new axes will be created.
738- *scale* scaling factor for the flows
739- *scale* sizes the width of the paths in order to
740- maintain proper layout. The same scale is applied
741- to all subdiagrams. The value should be chosen
742- such that the product of the scale and the sum of
743- the inputs is approximately 1.0 (and the product of
744- the scale and the sum of the outputs is
745- approximately -1.0).
746- *unit* string representing the physical unit associated
747- with the flow quantities
748- If *unit* is None, then none of the quantities are
749- labeled.
750- *format* a Python number formatting string to be used in
751- labeling the flow as a quantity (i.e., a number
752- times a unit, where the unit is given)
753- *gap* space between paths that break in/break away
754- to/from the top or bottom
755- *radius* inner radius of the vertical paths
756- *shoulder* size of the shoulders of output arrowS
757- *offset* text offset (from the dip or tip of the arrow)
758- *head_angle* angle of the arrow heads (and negative of the angle
759- of the tails) [deg]
760- *margin* minimum space between Sankey outlines and the edge
761- of the plot area
762- *tolerance* acceptable maximum of the magnitude of the sum of
763- flows
764- The magnitude of the sum of connected flows cannot
765- be greater than *tolerance*.
766- =============== ===================================================
767-
768- The optional arguments listed above are applied to all subdiagrams so
769- that there is consistent alignment and formatting.
770-
771- If :class:`Sankey` is instantiated with any keyword arguments other
772- than those explicitly listed above (``**kwargs``), they will be passed
773- to :meth:`add`, which will create the first subdiagram.
774-
775- In order to draw a complex Sankey diagram, create an instance of
776- :class:`Sankey` by calling it without any kwargs::
777-
778- sankey = Sankey()
779-
780- Then add simple Sankey sub-diagrams::
781-
782- sankey.add() # 1
783- sankey.add() # 2
784- #...
785- sankey.add() # n
786-
787- Finally, create the full diagram::
788-
789- sankey.finish()
790-
791- Or, instead, simply daisy-chain those calls::
792-
793- Sankey().add().add... .add().finish()
794-
795- .. seealso::
796-
797- :meth:`add`
798- :meth:`finish`
799-
800848
801- **Examples:**
802-
803- .. plot:: mpl_examples/api/sankey_demo_basics.py
804- """
805- # Check the arguments.
806- assert gap >= 0 , (
807- "The gap is negative.\n This isn't allowed because it "
808- "would cause the paths to overlap." )
809- assert radius <= gap , (
810- "The inner radius is greater than the path spacing.\n "
811- "This isn't allowed because it would cause the paths to overlap." )
812- assert head_angle >= 0 , (
813- "The angle is negative.\n This isn't allowed "
814- "because it would cause inputs to look like "
815- "outputs and vice versa." )
816- assert tolerance >= 0 , (
817- "The tolerance is negative.\n It must be a magnitude." )
818-
819- # Create axes if necessary.
820- if ax is None :
821- import matplotlib .pyplot as plt
822- fig = plt .figure ()
823- ax = fig .add_subplot (1 , 1 , 1 , xticks = [], yticks = [])
824-
825- self .diagrams = []
826-
827- # Store the inputs.
828- self .ax = ax
829- self .unit = unit
830- self .format = format
831- self .scale = scale
832- self .gap = gap
833- self .radius = radius
834- self .shoulder = shoulder
835- self .offset = offset
836- self .margin = margin
837- self .pitch = np .tan (np .pi * (1 - head_angle / 180.0 ) / 2.0 )
838- self .tolerance = tolerance
839-
840- # Initialize the vertices of tight box around the diagram(s).
841- self .extent = np .array ((np .inf , - np .inf , np .inf , - np .inf ))
842-
843- # If there are any kwargs, create the first subdiagram.
844- if len (kwargs ):
845- self .add (** kwargs )
0 commit comments