Динамически меняющиеся yticks - PullRequest
0 голосов
/ 07 ноября 2018
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

Я хочу написать эту функцию простым способом, она становится все более сложной для понимания. Я новичок в Python, может кто-нибудь помочь мне написать это. Цель этого - динамическое изменение y тиков

например: 1000000 -> 1M, 1000000000 -> 1B

1 Ответ

0 голосов
/ 07 ноября 2018

Вот как я бы упростил функцию:

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

И сравнение между оригинальным и модифицированным:

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())))

Результаты сравнения:

          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 . О плаваниях в Python.

Использование >= 1 в этом самом коде не должно быть проблемой практически в любом случае. Но рассмотрим пример:

a = 0
a += 1.01 / 2.03
a -= 1 / 2.03
a -= .01 / 2.03

a должен быть равен нулю после всех этих операций, но на моем компьютере a equlas to -6.938893903907228e-18, потому что точность ограничена. Вы должны учитывать этот факт, когда хотите проверить равенство между числами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...