@@ -396,8 +396,8 @@ def _fix_small_number(self, x, string, precision_offset=2):
396396 # Format with precision below floating point error
397397 x -= getattr (self , 'offset' , 0 ) # guard against API change
398398 x /= 10 ** getattr (self , 'orderOfMagnitude' , 0 ) # guard against API change
399- precision_true = int ( abs ( np . log10 ( abs ( x )) // 1 ))
400- precision_max = np .finfo (type (x )).precision - precision_offset
399+ precision_true = max ( 0 , self . _decimal_place ( x ))
400+ precision_max = max ( 0 , np .finfo (type (x )).precision - precision_offset )
401401 precision = min (precision_true , precision_max )
402402 string = ('{:.%df}' % precision ).format (x )
403403
@@ -426,6 +426,17 @@ def _get_default_decimal_point(use_locale=None):
426426 use_locale = _not_none (use_locale , rc ['formatter.use_locale' ])
427427 return locale .localeconv ()['decimal_point' ] if use_locale else '.'
428428
429+ @staticmethod
430+ def _decimal_place (x ):
431+ """
432+ Return the decimal place of the number (e.g., 100 is -2 and 0.01 is 2).
433+ """
434+ if x == 0 :
435+ digits = 0
436+ else :
437+ digits = - int (np .log10 (abs (x )) // 1 )
438+ return digits
439+
429440 @staticmethod
430441 def _minus_format (string ):
431442 """
@@ -542,31 +553,36 @@ class SigFigFormatter(mticker.Formatter):
542553 Format numbers by retaining the specified number of significant digits.
543554 """
544555 @docstring ._snippet_manager
545- def __init__ (self , sigfig = 3 , zerotrim = None ):
556+ def __init__ (self , sigfig = None , zerotrim = None , base = None ):
546557 """
547558 Parameters
548559 ----------
549560 sigfig : float, optional
550- The number of significant digits.
561+ The number of significant digits. Default is ``3``.
551562 %(ticker.zerotrim)s
563+ base : float, optional
564+ The base unit for rounding. Default is ``1``. For example
565+ ``SigFigFormatter(2, base=5)`` rounds to the nearest 5 with
566+ up to 2 significant digits (e.g., 87 --> 85, 8.7 --> 8.5).
552567 """
553- self ._sigfig = sigfig
568+ self ._sigfig = _not_none ( sigfig , 3 )
554569 self ._zerotrim = _not_none (zerotrim , rc ['formatter.zerotrim' ])
570+ self ._base = _not_none (base , 1 )
555571
556572 @docstring ._snippet_manager
557573 def __call__ (self , x , pos = None ): # noqa: U100
558574 """
559575 %(ticker.call)s
560576 """
561- # Limit digits to significant figures
562- if x == 0 :
563- digits = 0
564- else :
565- digits = - int (np .log10 (abs (x )) // 1 )
577+ # Limit to significant figures
578+ digits = AutoFormatter ._decimal_place (x ) + self ._sigfig - 1
579+ scale = self ._base * 10 ** - digits
580+ x = scale * round (x / scale )
581+
582+ # Create the string
566583 decimal_point = AutoFormatter ._get_default_decimal_point ()
567- digits += self ._sigfig - 1
568- x = np .round (x , digits )
569- string = ('{:.%df}' % max (0 , digits )).format (x )
584+ precision = max (0 , digits ) + max (0 , AutoFormatter ._decimal_place (self ._base ))
585+ string = ('{:.%df}' % precision ).format (x )
570586 string = string .replace ('.' , decimal_point )
571587
572588 # Custom string formatting
0 commit comments