@@ -914,6 +914,16 @@ def set_locs(self, locs=None):
914914 except AttributeError :
915915 pass
916916
917+ if vmin > vmax :
918+ vmin , vmax = vmax , vmin
919+
920+ if linthresh is None and vmin <= 0 :
921+ # It's probably a colorbar with
922+ # a format kwarg setting a LogFormatter in the manner
923+ # that worked with 1.5.x, but that doesn't work now.
924+ self ._sublabels = set ((1 ,)) # label powers of base
925+ return
926+
917927 if linthresh is not None : # symlog
918928 # Only compute the number of decades in the logarithmic part of the
919929 # axis
@@ -951,7 +961,7 @@ def __call__(self, x, pos=None):
951961 vmin , vmax = mtransforms .nonsingular (vmin , vmax , expander = 0.05 )
952962 d = abs (vmax - vmin )
953963 b = self ._base
954- if x == 0.0 :
964+ if x == 0.0 : # Symlog
955965 return '0'
956966 sign = np .sign (x )
957967 x = abs (x )
@@ -2032,36 +2042,41 @@ def view_limits(self, vmin, vmax):
20322042 'Try to choose the view limits intelligently'
20332043 b = self ._base
20342044
2035- if vmax < vmin :
2036- vmin , vmax = vmax , vmin
2045+ vmin , vmax = self .nonsingular (vmin , vmax )
20372046
20382047 if self .axis .axes .name == 'polar' :
20392048 vmax = math .ceil (math .log (vmax ) / math .log (b ))
20402049 vmin = b ** (vmax - self .numdecs )
2041- return vmin , vmax
2042-
2043- minpos = self .axis .get_minpos ()
2044-
2045- if minpos <= 0 or not np .isfinite (minpos ):
2046- raise ValueError (
2047- "Data has no positive values, and therefore can not be "
2048- "log-scaled." )
2049-
2050- if vmin <= 0 :
2051- vmin = minpos
20522050
20532051 if rcParams ['axes.autolimit_mode' ] == 'round_numbers' :
20542052 if not is_decade (vmin , self ._base ):
20552053 vmin = decade_down (vmin , self ._base )
20562054 if not is_decade (vmax , self ._base ):
20572055 vmax = decade_up (vmax , self ._base )
20582056
2059- if vmin == vmax :
2060- vmin = decade_down (vmin , self ._base )
2061- vmax = decade_up (vmax , self ._base )
2057+ return vmin , vmax
20622058
2063- result = mtransforms .nonsingular (vmin , vmax )
2064- return result
2059+ def nonsingular (self , vmin , vmax ):
2060+ if not np .isfinite (vmin ) or not np .isfinite (vmax ):
2061+ return 1 , 10 # initial range, no data plotted yet
2062+
2063+ if vmin > vmax :
2064+ vmin , vmax = vmax , vmin
2065+ if vmax <= 0 :
2066+ warnings .warn (
2067+ "Data has no positive values, and therefore cannot be "
2068+ "log-scaled." )
2069+ return 1 , 10
2070+
2071+ minpos = self .axis .get_minpos ()
2072+ if not np .isfinite (minpos ):
2073+ minpos = 1e-300 # This should never take effect.
2074+ if vmin <= 0 :
2075+ vmin = minpos
2076+ if vmin == vmax :
2077+ vmin = decade_down (vmin , self ._base )
2078+ vmax = decade_up (vmax , self ._base )
2079+ return vmin , vmax
20652080
20662081
20672082class SymmetricalLogLocator (Locator ):
@@ -2260,32 +2275,7 @@ def tick_values(self, vmin, vmax):
22602275 if hasattr (self .axis , 'axes' ) and self .axis .axes .name == 'polar' :
22612276 raise NotImplementedError ('Polar axis cannot be logit scaled yet' )
22622277
2263- # what to do if a window beyond ]0, 1[ is chosen
2264- if vmin <= 0.0 :
2265- if self .axis is not None :
2266- vmin = self .axis .get_minpos ()
2267-
2268- if (vmin <= 0.0 ) or (not np .isfinite (vmin )):
2269- raise ValueError (
2270- "Data has no values in ]0, 1[ and therefore can not be "
2271- "logit-scaled." )
2272-
2273- # NOTE: for vmax, we should query a property similar to get_minpos, but
2274- # related to the maximal, less-than-one data point. Unfortunately,
2275- # get_minpos is defined very deep in the BBox and updated with data,
2276- # so for now we use the trick below.
2277- if vmax >= 1.0 :
2278- if self .axis is not None :
2279- vmax = 1 - self .axis .get_minpos ()
2280-
2281- if (vmax >= 1.0 ) or (not np .isfinite (vmax )):
2282- raise ValueError (
2283- "Data has no values in ]0, 1[ and therefore can not be "
2284- "logit-scaled." )
2285-
2286- if vmax < vmin :
2287- vmin , vmax = vmax , vmin
2288-
2278+ vmin , vmax = self .nonsingular (vmin , vmax )
22892279 vmin = np .log10 (vmin / (1 - vmin ))
22902280 vmax = np .log10 (vmax / (1 - vmax ))
22912281
@@ -2320,6 +2310,36 @@ def tick_values(self, vmin, vmax):
23202310
23212311 return self .raise_if_exceeds (np .array (ticklocs ))
23222312
2313+ def nonsingular (self , vmin , vmax ):
2314+ initial_range = (1e-7 , 1 - 1e-7 )
2315+ if not np .isfinite (vmin ) or not np .isfinite (vmax ):
2316+ return initial_range # no data plotted yet
2317+
2318+ if vmin > vmax :
2319+ vmin , vmax = vmax , vmin
2320+
2321+ # what to do if a window beyond ]0, 1[ is chosen
2322+ if self .axis is not None :
2323+ minpos = self .axis .get_minpos ()
2324+ if not np .isfinite (minpos ):
2325+ return initial_range # again, no data plotted
2326+ else :
2327+ minpos = 1e-7 # should not occur in normal use
2328+
2329+ # NOTE: for vmax, we should query a property similar to get_minpos, but
2330+ # related to the maximal, less-than-one data point. Unfortunately,
2331+ # Bbox._minpos is defined very deep in the BBox and updated with data,
2332+ # so for now we use 1 - minpos as a substitute.
2333+
2334+ if vmin <= 0 :
2335+ vmin = minpos
2336+ if vmax >= 1 :
2337+ vmax = 1 - minpos
2338+ if vmin == vmax :
2339+ return 0.1 * vmin , 1 - 0.1 * vmin
2340+
2341+ return vmin , vmax
2342+
23232343
23242344class AutoLocator (MaxNLocator ):
23252345 def __init__ (self ):
0 commit comments