@@ -914,6 +914,16 @@ def set_locs(self, locs=None):
914
914
except AttributeError :
915
915
pass
916
916
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
+
917
927
if linthresh is not None : # symlog
918
928
# Only compute the number of decades in the logarithmic part of the
919
929
# axis
@@ -951,7 +961,7 @@ def __call__(self, x, pos=None):
951
961
vmin , vmax = mtransforms .nonsingular (vmin , vmax , expander = 0.05 )
952
962
d = abs (vmax - vmin )
953
963
b = self ._base
954
- if x == 0.0 :
964
+ if x == 0.0 : # Symlog
955
965
return '0'
956
966
sign = np .sign (x )
957
967
x = abs (x )
@@ -2032,36 +2042,41 @@ def view_limits(self, vmin, vmax):
2032
2042
'Try to choose the view limits intelligently'
2033
2043
b = self ._base
2034
2044
2035
- if vmax < vmin :
2036
- vmin , vmax = vmax , vmin
2045
+ vmin , vmax = self .nonsingular (vmin , vmax )
2037
2046
2038
2047
if self .axis .axes .name == 'polar' :
2039
2048
vmax = math .ceil (math .log (vmax ) / math .log (b ))
2040
2049
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
2052
2050
2053
2051
if rcParams ['axes.autolimit_mode' ] == 'round_numbers' :
2054
2052
if not is_decade (vmin , self ._base ):
2055
2053
vmin = decade_down (vmin , self ._base )
2056
2054
if not is_decade (vmax , self ._base ):
2057
2055
vmax = decade_up (vmax , self ._base )
2058
2056
2059
- if vmin == vmax :
2060
- vmin = decade_down (vmin , self ._base )
2061
- vmax = decade_up (vmax , self ._base )
2057
+ return vmin , vmax
2062
2058
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
2065
2080
2066
2081
2067
2082
class SymmetricalLogLocator (Locator ):
@@ -2260,32 +2275,7 @@ def tick_values(self, vmin, vmax):
2260
2275
if hasattr (self .axis , 'axes' ) and self .axis .axes .name == 'polar' :
2261
2276
raise NotImplementedError ('Polar axis cannot be logit scaled yet' )
2262
2277
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 )
2289
2279
vmin = np .log10 (vmin / (1 - vmin ))
2290
2280
vmax = np .log10 (vmax / (1 - vmax ))
2291
2281
@@ -2320,6 +2310,36 @@ def tick_values(self, vmin, vmax):
2320
2310
2321
2311
return self .raise_if_exceeds (np .array (ticklocs ))
2322
2312
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
+
2323
2343
2324
2344
class AutoLocator (MaxNLocator ):
2325
2345
def __init__ (self ):
0 commit comments