@@ -332,13 +332,11 @@ def test_basic(self):
332
332
with pytest .raises (ValueError ):
333
333
loc .tick_values (0 , 1000 )
334
334
335
- test_value = np .array ([1.00000000e-05 , 1.00000000e-03 , 1.00000000e-01 ,
336
- 1.00000000e+01 , 1.00000000e+03 , 1.00000000e+05 ,
337
- 1.00000000e+07 , 1.000000000e+09 ])
335
+ test_value = np .array ([1e-5 , 1e-3 , 1e-1 , 1e+1 , 1e+3 , 1e+5 , 1e+7 ])
338
336
assert_almost_equal (loc .tick_values (0.001 , 1.1e5 ), test_value )
339
337
340
338
loc = mticker .LogLocator (base = 2 )
341
- test_value = np .array ([0 .5 , 1. , 2. , 4. , 8. , 16. , 32. , 64. , 128. , 256 . ])
339
+ test_value = np .array ([.5 , 1. , 2. , 4. , 8. , 16. , 32. , 64. , 128. ])
342
340
assert_almost_equal (loc .tick_values (1 , 100 ), test_value )
343
341
344
342
def test_polar_axes (self ):
@@ -377,7 +375,7 @@ def test_tick_values_correct(self):
377
375
1.e+01 , 2.e+01 , 5.e+01 , 1.e+02 , 2.e+02 , 5.e+02 ,
378
376
1.e+03 , 2.e+03 , 5.e+03 , 1.e+04 , 2.e+04 , 5.e+04 ,
379
377
1.e+05 , 2.e+05 , 5.e+05 , 1.e+06 , 2.e+06 , 5.e+06 ,
380
- 1.e+07 , 2.e+07 , 5.e+07 , 1.e+08 , 2.e+08 , 5.e+08 ])
378
+ 1.e+07 , 2.e+07 , 5.e+07 ])
381
379
assert_almost_equal (ll .tick_values (1 , 1e7 ), test_value )
382
380
383
381
def test_tick_values_not_empty (self ):
@@ -387,8 +385,7 @@ def test_tick_values_not_empty(self):
387
385
1.e+01 , 2.e+01 , 5.e+01 , 1.e+02 , 2.e+02 , 5.e+02 ,
388
386
1.e+03 , 2.e+03 , 5.e+03 , 1.e+04 , 2.e+04 , 5.e+04 ,
389
387
1.e+05 , 2.e+05 , 5.e+05 , 1.e+06 , 2.e+06 , 5.e+06 ,
390
- 1.e+07 , 2.e+07 , 5.e+07 , 1.e+08 , 2.e+08 , 5.e+08 ,
391
- 1.e+09 , 2.e+09 , 5.e+09 ])
388
+ 1.e+07 , 2.e+07 , 5.e+07 , 1.e+08 , 2.e+08 , 5.e+08 ])
392
389
assert_almost_equal (ll .tick_values (1 , 1e8 ), test_value )
393
390
394
391
def test_multiple_shared_axes (self ):
@@ -1913,14 +1910,54 @@ def test_bad_locator_subs(sub):
1913
1910
ll .set_params (subs = sub )
1914
1911
1915
1912
1916
- @pytest .mark .parametrize ('numticks' , [1 , 2 , 3 , 9 ])
1913
+ @pytest .mark .parametrize ("numticks, lims, ticks" , [
1914
+ (1 , (.5 , 5 ), [.1 , 1 , 10 ]),
1915
+ (2 , (.5 , 5 ), [.1 , 1 , 10 ]),
1916
+ (3 , (.5 , 5 ), [.1 , 1 , 10 ]),
1917
+ (9 , (.5 , 5 ), [.1 , 1 , 10 ]),
1918
+ (1 , (.5 , 50 ), [.1 , 10 , 1_000 ]),
1919
+ (2 , (.5 , 50 ), [.1 , 1 , 10 , 100 ]),
1920
+ (3 , (.5 , 50 ), [.1 , 1 , 10 , 100 ]),
1921
+ (9 , (.5 , 50 ), [.1 , 1 , 10 , 100 ]),
1922
+ (1 , (.5 , 500 ), [.1 , 10 , 1_000 ]),
1923
+ (2 , (.5 , 500 ), [.01 , 1 , 100 , 10_000 ]),
1924
+ (3 , (.5 , 500 ), [.1 , 1 , 10 , 100 , 1_000 ]),
1925
+ (9 , (.5 , 500 ), [.1 , 1 , 10 , 100 , 1_000 ]),
1926
+ (1 , (.5 , 5000 ), [.1 , 100 , 100_000 ]),
1927
+ (2 , (.5 , 5000 ), [.001 , 1 , 1_000 , 1_000_000 ]),
1928
+ (3 , (.5 , 5000 ), [.001 , 1 , 1_000 , 1_000_000 ]),
1929
+ (9 , (.5 , 5000 ), [.1 , 1 , 10 , 100 , 1_000 , 10_000 ]),
1930
+ ])
1917
1931
@mpl .style .context ('default' )
1918
- def test_small_range_loglocator (numticks ):
1919
- ll = mticker .LogLocator ()
1920
- ll .set_params (numticks = numticks )
1921
- for top in [5 , 7 , 9 , 11 , 15 , 50 , 100 , 1000 ]:
1922
- ticks = ll .tick_values (.5 , top )
1923
- assert (np .diff (np .log10 (ll .tick_values (6 , 150 ))) == 1 ).all ()
1932
+ def test_small_range_loglocator (numticks , lims , ticks ):
1933
+ ll = mticker .LogLocator (numticks = numticks )
1934
+ assert_array_equal (ll .tick_values (* lims ), ticks )
1935
+
1936
+
1937
+ @mpl .style .context ('default' )
1938
+ def test_loglocator_properties ():
1939
+ # Test that LogLocator returns ticks satisfying basic desirable properties
1940
+ # for a wide range of inputs.
1941
+ max_numticks = 8
1942
+ pow_end = 20
1943
+ for numticks , (lo , hi ) in itertools .product (
1944
+ range (1 , max_numticks + 1 ), itertools .combinations (range (pow_end ), 2 )):
1945
+ ll = mticker .LogLocator (numticks = numticks )
1946
+ decades = np .log10 (ll .tick_values (10 ** lo , 10 ** hi )).round ().astype (int )
1947
+ # There are no more ticks than the requested number, plus exactly one
1948
+ # tick below and one tick above the limits.
1949
+ assert len (decades ) <= numticks + 2
1950
+ assert decades [0 ] < lo <= decades [1 ]
1951
+ assert decades [- 2 ] <= hi < decades [- 1 ]
1952
+ stride , = {* np .diff (decades )} # Extract the (constant) stride.
1953
+ # Either the ticks are on integer multiples of the stride...
1954
+ if not (decades % stride == 0 ).all ():
1955
+ # ... or (for this given stride) no offset would be acceptable,
1956
+ # i.e. they would either result in fewer ticks than the selected
1957
+ # solution, or more than the requested number of ticks.
1958
+ for offset in range (0 , stride ):
1959
+ alt_decades = range (lo + offset , hi + 1 , stride )
1960
+ assert len (alt_decades ) < len (decades ) or len (alt_decades ) > numticks
1924
1961
1925
1962
1926
1963
def test_NullFormatter ():
0 commit comments