Dynamically changing yticks
up vote
0
down vote
favorite
def y_ticks(y, pos):
decades = [1e9, 1e6, 1e3, 1e0 ]
suffix = ['B', 'M', 'K', '']
if y == 0:
return str(0)
for i, d in enumerate(decades):
if np.abs(y) >=d:
val = y/float(d)
signf = len(str(val).split('.')[1])
if signf == 0:
return '{val:d} {suffix}'.format(val=int(val), suffix=suffix[i])
else:
if signf == 1:
if str(val).split('.')[1] == '0':
return '{val:d} {suffix}'.format(val=int(round(val)), suffix=suffix[i])
tx = '{'+'val:.{signf}f'.format(signf = signf) +'} {suffix}'
return tx.format(val=val, suffix=suffix[i])
return y
I want to write this function in simple way,its getting way to complex to understand. I am new to python can someone help me writing this. The aim of this to change y ticks dynamically
for example: 1000000 -> 1M, 1000000000 ->1B
python python-3.x python-2.7 function matplotlib
add a comment |
up vote
0
down vote
favorite
def y_ticks(y, pos):
decades = [1e9, 1e6, 1e3, 1e0 ]
suffix = ['B', 'M', 'K', '']
if y == 0:
return str(0)
for i, d in enumerate(decades):
if np.abs(y) >=d:
val = y/float(d)
signf = len(str(val).split('.')[1])
if signf == 0:
return '{val:d} {suffix}'.format(val=int(val), suffix=suffix[i])
else:
if signf == 1:
if str(val).split('.')[1] == '0':
return '{val:d} {suffix}'.format(val=int(round(val)), suffix=suffix[i])
tx = '{'+'val:.{signf}f'.format(signf = signf) +'} {suffix}'
return tx.format(val=val, suffix=suffix[i])
return y
I want to write this function in simple way,its getting way to complex to understand. I am new to python can someone help me writing this. The aim of this to change y ticks dynamically
for example: 1000000 -> 1M, 1000000000 ->1B
python python-3.x python-2.7 function matplotlib
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
def y_ticks(y, pos):
decades = [1e9, 1e6, 1e3, 1e0 ]
suffix = ['B', 'M', 'K', '']
if y == 0:
return str(0)
for i, d in enumerate(decades):
if np.abs(y) >=d:
val = y/float(d)
signf = len(str(val).split('.')[1])
if signf == 0:
return '{val:d} {suffix}'.format(val=int(val), suffix=suffix[i])
else:
if signf == 1:
if str(val).split('.')[1] == '0':
return '{val:d} {suffix}'.format(val=int(round(val)), suffix=suffix[i])
tx = '{'+'val:.{signf}f'.format(signf = signf) +'} {suffix}'
return tx.format(val=val, suffix=suffix[i])
return y
I want to write this function in simple way,its getting way to complex to understand. I am new to python can someone help me writing this. The aim of this to change y ticks dynamically
for example: 1000000 -> 1M, 1000000000 ->1B
python python-3.x python-2.7 function matplotlib
def y_ticks(y, pos):
decades = [1e9, 1e6, 1e3, 1e0 ]
suffix = ['B', 'M', 'K', '']
if y == 0:
return str(0)
for i, d in enumerate(decades):
if np.abs(y) >=d:
val = y/float(d)
signf = len(str(val).split('.')[1])
if signf == 0:
return '{val:d} {suffix}'.format(val=int(val), suffix=suffix[i])
else:
if signf == 1:
if str(val).split('.')[1] == '0':
return '{val:d} {suffix}'.format(val=int(round(val)), suffix=suffix[i])
tx = '{'+'val:.{signf}f'.format(signf = signf) +'} {suffix}'
return tx.format(val=val, suffix=suffix[i])
return y
I want to write this function in simple way,its getting way to complex to understand. I am new to python can someone help me writing this. The aim of this to change y ticks dynamically
for example: 1000000 -> 1M, 1000000000 ->1B
python python-3.x python-2.7 function matplotlib
python python-3.x python-2.7 function matplotlib
asked Nov 7 at 6:03
Terry
55
55
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
accepted
This is how I would simplify the function:
def y_ticks_(y, pos):
# map to choose suffix
value_to_suffix = {1e3: ' K', 1e6: ' M', 1e9: ' B'}
# initialize value and suffix
value = y
suffix = ''
# choose appropriate suffix
for val in sorted(value_to_suffix):
# "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits.
if abs(y / val) > 1 - 10 ** -10:
value = y / val
suffix = value_to_suffix[val]
else:
break
# create string from value and suffix
y_new = '{:.3f}'.format(value).strip('0').strip('.') + suffix
return y_new
And comparision between the original one and the modified one:
print('{:>15}|{:>15}|{:>15}|'.format('value', 'original', 'new'))
print('-' * 48)
for val in [10, -5, 102, -200, 1001, -1234, 15200, -22000, 99001,
1e5, 1e6, 1e7, 1999999, 1999999.99, 1e9]:
print(
'{:>15}|{:>15}|{:>15}|'
.format(val, y_ticks(val, list()), y_ticks_(val, list())))
Comparision results:
value| original| new|
------------------------------------------------
10| 10 | 10|
-5| -5 | -5|
102| 102 | 102|
-200| -200 | -200|
1001| 1.001 K| 1.001 K|
-1234| -1.234 K| -1.234 K|
15200| 15.2 K| 15.2 K|
-22000| -22 K| -22 K|
99001| 99.001 K| 99.001 K|
100000.0| 100 K| 100 K|
1000000.0| 1 M| 1 M|
10000000.0| 10 M| 10 M|
1999999| 1.999999 M| 2 M|
1999999.99| 1.99999999 M| 2 M|
1000000000.0| 1 B| 1 B|
EDIT. About floats in Python.
Using >= 1
in this very code should not be a problem in almost any case. But consider example:
a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03
a
should be zero after all these operations but on my machine a
equlas to -6.938893903907228e-18
because precision is limited. You have to take this fact into account when you want to check the equality between floats.
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
Could you please explain?
– Terry
Nov 8 at 8:14
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
@Terry I added small example about floats. In short, you may use>= 1
in this code but be aware about floats if you check the equality between them in any programming language.
– Poolka
Nov 8 at 8:36
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
|
show 1 more comment
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
This is how I would simplify the function:
def y_ticks_(y, pos):
# map to choose suffix
value_to_suffix = {1e3: ' K', 1e6: ' M', 1e9: ' B'}
# initialize value and suffix
value = y
suffix = ''
# choose appropriate suffix
for val in sorted(value_to_suffix):
# "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits.
if abs(y / val) > 1 - 10 ** -10:
value = y / val
suffix = value_to_suffix[val]
else:
break
# create string from value and suffix
y_new = '{:.3f}'.format(value).strip('0').strip('.') + suffix
return y_new
And comparision between the original one and the modified one:
print('{:>15}|{:>15}|{:>15}|'.format('value', 'original', 'new'))
print('-' * 48)
for val in [10, -5, 102, -200, 1001, -1234, 15200, -22000, 99001,
1e5, 1e6, 1e7, 1999999, 1999999.99, 1e9]:
print(
'{:>15}|{:>15}|{:>15}|'
.format(val, y_ticks(val, list()), y_ticks_(val, list())))
Comparision results:
value| original| new|
------------------------------------------------
10| 10 | 10|
-5| -5 | -5|
102| 102 | 102|
-200| -200 | -200|
1001| 1.001 K| 1.001 K|
-1234| -1.234 K| -1.234 K|
15200| 15.2 K| 15.2 K|
-22000| -22 K| -22 K|
99001| 99.001 K| 99.001 K|
100000.0| 100 K| 100 K|
1000000.0| 1 M| 1 M|
10000000.0| 10 M| 10 M|
1999999| 1.999999 M| 2 M|
1999999.99| 1.99999999 M| 2 M|
1000000000.0| 1 B| 1 B|
EDIT. About floats in Python.
Using >= 1
in this very code should not be a problem in almost any case. But consider example:
a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03
a
should be zero after all these operations but on my machine a
equlas to -6.938893903907228e-18
because precision is limited. You have to take this fact into account when you want to check the equality between floats.
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
Could you please explain?
– Terry
Nov 8 at 8:14
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
@Terry I added small example about floats. In short, you may use>= 1
in this code but be aware about floats if you check the equality between them in any programming language.
– Poolka
Nov 8 at 8:36
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
|
show 1 more comment
up vote
0
down vote
accepted
This is how I would simplify the function:
def y_ticks_(y, pos):
# map to choose suffix
value_to_suffix = {1e3: ' K', 1e6: ' M', 1e9: ' B'}
# initialize value and suffix
value = y
suffix = ''
# choose appropriate suffix
for val in sorted(value_to_suffix):
# "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits.
if abs(y / val) > 1 - 10 ** -10:
value = y / val
suffix = value_to_suffix[val]
else:
break
# create string from value and suffix
y_new = '{:.3f}'.format(value).strip('0').strip('.') + suffix
return y_new
And comparision between the original one and the modified one:
print('{:>15}|{:>15}|{:>15}|'.format('value', 'original', 'new'))
print('-' * 48)
for val in [10, -5, 102, -200, 1001, -1234, 15200, -22000, 99001,
1e5, 1e6, 1e7, 1999999, 1999999.99, 1e9]:
print(
'{:>15}|{:>15}|{:>15}|'
.format(val, y_ticks(val, list()), y_ticks_(val, list())))
Comparision results:
value| original| new|
------------------------------------------------
10| 10 | 10|
-5| -5 | -5|
102| 102 | 102|
-200| -200 | -200|
1001| 1.001 K| 1.001 K|
-1234| -1.234 K| -1.234 K|
15200| 15.2 K| 15.2 K|
-22000| -22 K| -22 K|
99001| 99.001 K| 99.001 K|
100000.0| 100 K| 100 K|
1000000.0| 1 M| 1 M|
10000000.0| 10 M| 10 M|
1999999| 1.999999 M| 2 M|
1999999.99| 1.99999999 M| 2 M|
1000000000.0| 1 B| 1 B|
EDIT. About floats in Python.
Using >= 1
in this very code should not be a problem in almost any case. But consider example:
a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03
a
should be zero after all these operations but on my machine a
equlas to -6.938893903907228e-18
because precision is limited. You have to take this fact into account when you want to check the equality between floats.
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
Could you please explain?
– Terry
Nov 8 at 8:14
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
@Terry I added small example about floats. In short, you may use>= 1
in this code but be aware about floats if you check the equality between them in any programming language.
– Poolka
Nov 8 at 8:36
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
|
show 1 more comment
up vote
0
down vote
accepted
up vote
0
down vote
accepted
This is how I would simplify the function:
def y_ticks_(y, pos):
# map to choose suffix
value_to_suffix = {1e3: ' K', 1e6: ' M', 1e9: ' B'}
# initialize value and suffix
value = y
suffix = ''
# choose appropriate suffix
for val in sorted(value_to_suffix):
# "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits.
if abs(y / val) > 1 - 10 ** -10:
value = y / val
suffix = value_to_suffix[val]
else:
break
# create string from value and suffix
y_new = '{:.3f}'.format(value).strip('0').strip('.') + suffix
return y_new
And comparision between the original one and the modified one:
print('{:>15}|{:>15}|{:>15}|'.format('value', 'original', 'new'))
print('-' * 48)
for val in [10, -5, 102, -200, 1001, -1234, 15200, -22000, 99001,
1e5, 1e6, 1e7, 1999999, 1999999.99, 1e9]:
print(
'{:>15}|{:>15}|{:>15}|'
.format(val, y_ticks(val, list()), y_ticks_(val, list())))
Comparision results:
value| original| new|
------------------------------------------------
10| 10 | 10|
-5| -5 | -5|
102| 102 | 102|
-200| -200 | -200|
1001| 1.001 K| 1.001 K|
-1234| -1.234 K| -1.234 K|
15200| 15.2 K| 15.2 K|
-22000| -22 K| -22 K|
99001| 99.001 K| 99.001 K|
100000.0| 100 K| 100 K|
1000000.0| 1 M| 1 M|
10000000.0| 10 M| 10 M|
1999999| 1.999999 M| 2 M|
1999999.99| 1.99999999 M| 2 M|
1000000000.0| 1 B| 1 B|
EDIT. About floats in Python.
Using >= 1
in this very code should not be a problem in almost any case. But consider example:
a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03
a
should be zero after all these operations but on my machine a
equlas to -6.938893903907228e-18
because precision is limited. You have to take this fact into account when you want to check the equality between floats.
This is how I would simplify the function:
def y_ticks_(y, pos):
# map to choose suffix
value_to_suffix = {1e3: ' K', 1e6: ' M', 1e9: ' B'}
# initialize value and suffix
value = y
suffix = ''
# choose appropriate suffix
for val in sorted(value_to_suffix):
# "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits.
if abs(y / val) > 1 - 10 ** -10:
value = y / val
suffix = value_to_suffix[val]
else:
break
# create string from value and suffix
y_new = '{:.3f}'.format(value).strip('0').strip('.') + suffix
return y_new
And comparision between the original one and the modified one:
print('{:>15}|{:>15}|{:>15}|'.format('value', 'original', 'new'))
print('-' * 48)
for val in [10, -5, 102, -200, 1001, -1234, 15200, -22000, 99001,
1e5, 1e6, 1e7, 1999999, 1999999.99, 1e9]:
print(
'{:>15}|{:>15}|{:>15}|'
.format(val, y_ticks(val, list()), y_ticks_(val, list())))
Comparision results:
value| original| new|
------------------------------------------------
10| 10 | 10|
-5| -5 | -5|
102| 102 | 102|
-200| -200 | -200|
1001| 1.001 K| 1.001 K|
-1234| -1.234 K| -1.234 K|
15200| 15.2 K| 15.2 K|
-22000| -22 K| -22 K|
99001| 99.001 K| 99.001 K|
100000.0| 100 K| 100 K|
1000000.0| 1 M| 1 M|
10000000.0| 10 M| 10 M|
1999999| 1.999999 M| 2 M|
1999999.99| 1.99999999 M| 2 M|
1000000000.0| 1 B| 1 B|
EDIT. About floats in Python.
Using >= 1
in this very code should not be a problem in almost any case. But consider example:
a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03
a
should be zero after all these operations but on my machine a
equlas to -6.938893903907228e-18
because precision is limited. You have to take this fact into account when you want to check the equality between floats.
edited Nov 8 at 8:33
answered Nov 7 at 9:43
Poolka
859128
859128
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
Could you please explain?
– Terry
Nov 8 at 8:14
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
@Terry I added small example about floats. In short, you may use>= 1
in this code but be aware about floats if you check the equality between them in any programming language.
– Poolka
Nov 8 at 8:36
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
|
show 1 more comment
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
Could you please explain?
– Terry
Nov 8 at 8:14
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
@Terry I added small example about floats. In short, you may use>= 1
in this code but be aware about floats if you check the equality between them in any programming language.
– Poolka
Nov 8 at 8:36
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
that is looking ok, I am still confusing about # "> 1 - 10 ** -10" is used instead of ">= 1" because of how floats are represented in Python - precision is limited by 15 digits still confused instead of 1 we need to used 0.9999999 Do you any specific python doc based on that
– Terry
Nov 8 at 8:12
Could you please explain?
– Terry
Nov 8 at 8:14
Could you please explain?
– Terry
Nov 8 at 8:14
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
Inaddtion if I used 1 as below 'if abs(y / val) > 1:' if input is 1000 -> the output is also 1000 (which make thing works in my used case) while it should be like 1K
– Terry
Nov 8 at 8:23
@Terry I added small example about floats. In short, you may use
>= 1
in this code but be aware about floats if you check the equality between them in any programming language.– Poolka
Nov 8 at 8:36
@Terry I added small example about floats. In short, you may use
>= 1
in this code but be aware about floats if you check the equality between them in any programming language.– Poolka
Nov 8 at 8:36
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
gotcha, thank you so much I appreciate that
– Terry
Nov 9 at 8:59
|
show 1 more comment
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53184308%2fdynamically-changing-yticks%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password