Skip to content

Commit fce534c

Browse files
authored
Merge pull request #19187 from CharlesHe16/master
ENH: Support callable for formatting of Sankey labels
2 parents 2631206 + 35954a0 commit fce534c

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
Support callable for formatting of Sankey labels
2+
------------------------------------------------
3+
4+
The `format` parameter of `matplotlib.sankey.Sankey` can now accept callables.
5+
6+
This allows the use of an arbitrary function to label flows, for example allowing
7+
the mapping of numbers to emoji.
8+
9+
.. plot::
10+
11+
import matplotlib.pyplot as plt
12+
from matplotlib.sankey import Sankey
13+
import math
14+
15+
16+
def display_in_cats(values, min_cats, max_cats):
17+
def display_in_cat_scale(value):
18+
max_value = max(values, key=abs)
19+
number_cats_to_show = \
20+
max(min_cats, math.floor(abs(value) / max_value * max_cats))
21+
return str(number_cats_to_show * '🐱')
22+
23+
return display_in_cat_scale
24+
25+
26+
flows = [35, 15, 40, -20, -15, -5, -40, -10]
27+
orientations = [-1, 1, 0, 1, 1, 1, -1, -1]
28+
29+
# Cats are good, we want a strictly positive number of them
30+
min_cats = 1
31+
# More than four cats might be too much for some people
32+
max_cats = 4
33+
34+
cats_format = display_in_cats(flows, min_cats, max_cats)
35+
36+
sankey = Sankey(flows=flows, orientations=orientations, format=cats_format,
37+
offset=.1, head_angle=180, shoulder=0, scale=.010)
38+
39+
diagrams = sankey.finish()
40+
41+
diagrams[0].texts[2].set_text('')
42+
43+
plt.title(f'Sankey flows measured in cats \n'
44+
f'🐱 = {max(flows, key=abs) / max_cats}')
45+
46+
plt.show()

lib/matplotlib/sankey.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,12 @@ def __init__(self, ax=None, scale=1.0, unit='', format='%G', gap=0.25,
8383
unit : str
8484
The physical unit associated with the flow quantities. If *unit*
8585
is None, then none of the quantities are labeled.
86-
format : str
87-
A Python number formatting string to be used in labeling the flow
88-
as a quantity (i.e., a number times a unit, where the unit is
89-
given).
86+
format : str or callable
87+
A Python number formatting string or callable used to label the
88+
flows with their quantities (i.e., a number times a unit, where the
89+
unit is given). If a format string is given, the label will be
90+
``format % quantity``. If a callable is given, it will be called
91+
with ``quantity`` as an argument.
9092
gap : float
9193
Space between paths that break in/break away to/from the top or
9294
bottom.
@@ -739,7 +741,13 @@ def _get_angle(a, r):
739741
if label is None or angle is None:
740742
label = ''
741743
elif self.unit is not None:
742-
quantity = self.format % abs(number) + self.unit
744+
if isinstance(self.format, str):
745+
quantity = self.format % abs(number) + self.unit
746+
elif callable(self.format):
747+
quantity = self.format(number)
748+
else:
749+
raise TypeError(
750+
'format must be callable or a format string')
743751
if label != '':
744752
label += "\n"
745753
label += quantity

lib/matplotlib/tests/test_sankey.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@ def test_sankey():
1010
def test_label():
1111
s = Sankey(flows=[0.25], labels=['First'], orientations=[-1])
1212
assert s.diagrams[0].texts[0].get_text() == 'First\n0.25'
13+
14+
15+
def test_format_using_callable():
16+
# test using callable by slightly incrementing above label example
17+
18+
def show_three_decimal_places(value):
19+
return f'{value:.3f}'
20+
21+
s = Sankey(flows=[0.25], labels=['First'], orientations=[-1],
22+
format=show_three_decimal_places)
23+
24+
assert s.diagrams[0].texts[0].get_text() == 'First\n0.250'

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy