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










share|improve this question


























    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










    share|improve this question
























      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










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 7 at 6:03









      Terry

      55




      55
























          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.






          share|improve this answer























          • 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











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          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
































          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.






          share|improve this answer























          • 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















          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.






          share|improve this answer























          • 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













          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.






          share|improve this answer














          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          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


















          • 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


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          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




















































































          Popular posts from this blog

          横浜市

          Rostock

          Europa