8000 Merge pull request #22244 from jklymak/mnt-colorbar-locators-properties · matplotlib/matplotlib@6ddccef · GitHub
[go: up one dir, main page]

Skip to content

Commit 6ddccef

Browse files
authored
Merge pull request #22244 from jklymak/mnt-colorbar-locators-properties
MNT: colorbar locators properties
2 parents 695bc25 + 7277386 commit 6ddccef

File tree

2 files changed

+101
-29
lines changed

2 files changed

+101
-29
lines changed

lib/matplotlib/colorbar.py

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -440,9 +440,10 @@ def __init__(self, ax, mappable=None, *, cmap=None,
440440
linewidths=[0.5 * mpl.rcParams['axes.linewidth']])
441441
self.ax.add_collection(self.dividers)
442442

443-
self.locator = None
444-
self.minorlocator = None
445-
self.formatter = None
443+
self._locator = None
444+
self._minorlocator = None
445+
self._form 10000 atter = None
446+
self._minorformatter = None
446447
self.__scale = None # linear, log10 for now. Hopefully more?
447448

448449
if ticklocation == 'auto':
@@ -453,19 +454,19 @@ def __init__(self, ax, mappable=None, *, cmap=None,
453454
self._reset_locator_formatter_scale()
454455

455456
if np.iterable(ticks):
456-
self.locator = ticker.FixedLocator(ticks, nbins=len(ticks))
457+
self._locator = ticker.FixedLocator(ticks, nbins=len(ticks))
457458
else:
458-
self.locator = ticks # Handle default in _ticker()
459+
self._locator = ticks # Handle default in _ticker()
459460

460461
if isinstance(format, str):
461462
# Check format between FormatStrFormatter and StrMethodFormatter
462463
try:
463-
self.formatter = ticker.FormatStrFormatter(format)
464-
_ = self.formatter(0)
464+
self._formatter = ticker.FormatStrFormatter(format)
465+
_ = self._formatter(0)
465466
except TypeError:
466-
self.formatter = ticker.StrMethodFormatter(format)
467+
self._formatter = ticker.StrMethodFormatter(format)
467468
else:
468-
self.formatter = format # Assume it is a Formatter or None
469+
self._formatter = format # Assume it is a Formatter or None
469470
self._draw_all()
470471

471472
if isinstance(mappable, contour.ContourSet) and not mappable.filled:
@@ -486,6 +487,46 @@ def __init__(self, ax, mappable=None, *, cmap=None,
486487
# Set the cla function to the cbar's method to override it
487488
self.ax.cla = self._cbar_cla
488489

490+
@property
491+
def locator(self):
492+
"""Major tick `.Locator` for the colorbar."""
493+
return self._long_axis().get_major_locator()
494+
495+
@locator.setter
496+
def locator(self, loc):
497+
self._long_axis().set_major_locator(loc)
498+
self._locator = loc
499+
500+
@property
501+
def minorlocator(self):
502+
"""Minor tick `.Locator` for the colorbar."""
503+
return self._long_axis().get_minor_locator()
504+
505+
@minorlocator.setter
506+
def minorlocator(self, loc):
507+
self._long_axis().set_minor_locator(loc)
508+
self._minorlocator = loc
509+
510+
@property
511+
def formatter(self):
512+
"""Major tick label `.Formatter` for the colorbar."""
513+
return self._long_axis().get_major_formatter()
514+
515+
@formatter.setter
516+
def formatter(self, fmt):
517+
self._long_axis().set_major_formatter(fmt)
518+
self._formatter = fmt
519+
520+
@property
521+
def minorformatter(self):
522+
"""Minor tick `.Formatter` for the colorbar."""
523+
return self._long_axis().get_minor_formatter()
524+
525+
@minorformatter.setter
526+
def minorformatter(self, fmt):
527+
self._long_axis().set_minor_formatter(fmt)
528+
self._minorformatter = fmt
529+
489530
def _cbar_cla(self):
490531
"""Function to clear the interactive colorbar state."""
491532
for x in self._interactive_funcs:
@@ -778,11 +819,11 @@ def update_ticks(self):
778819
"""
779820
Setup the ticks and ticklabels. This should not be needed by users.
780821
"""
781-
# Get the locator and formatter; defaults to self.locator if not None.
822+
# Get the locator and formatter; defaults to self._locator if not None.
782823
self._get_ticker_locator_formatter()
783-
self._long_axis().set_major_locator(self.locator)
784-
self._long_axis().set_minor_locator(self.minorlocator)
785-
self._long_axis().set_major_formatter(self.formatter)
824+
self._long_axis().set_major_locator(self._locator)
825+
self._long_axis().set_minor_locator(self._minorlocator)
826+
self._long_axis().set_major_formatter(self._formatter)
786827

787828
def _get_ticker_locator_formatter(self):
788829
"""
@@ -794,13 +835,15 @@ def _get_ticker_locator_formatter(self):
794835
795836
Called by update_ticks...
796837
"""
797-
locator = self.locator
798-
formatter = self.formatter
799-
minorlocator = self.minorlocator
838+
locator = self._locator
839+
formatter = self._formatter
840+
minorlocator = self._minorlocator
800841
if isinstance(self.norm, colors.BoundaryNorm):
801842
b = self.norm.boundaries
802843
if locator is None:
803844
locator = ticker.FixedLocator(b, nbins=10)
845+
if minorlocator is None:
846+
minorlocator = ticker.FixedLocator(b)
804847
elif isinstance(self.norm, colors.NoNorm):
805848
if locator is None:
806849
# put ticks on integers between the boundaries of NoNorm
@@ -825,9 +868,9 @@ def _get_ticker_locator_formatter(self):
825868
if formatter is None:
826869
formatter = self._long_axis().get_major_formatter()
827870

828-
self.locator = locator
829-
self.formatter = formatter
830-
self.minorlocator = minorlocator
871+
self._locator = locator
872+
self._formatter = formatter
873+
self._minorlocator = minorlocator
831874
_log.debug('locator: %r', locator)
832875

833876
@_api.delete_parameter("3.5", "update_ticks")
@@ -851,10 +894,10 @@ def set_ticks(self, ticks, update_ticks=True, labels=None, *,
851894
if np.iterable(ticks):
852895
self._long_axis().set_ticks(ticks, labels=labels, minor=minor,
853896
**kwargs)
854-
self.locator = self._long_axis().get_major_locator()
897+
self._locator = self._long_axis().get_major_locator()
855898
else:
856-
self.locator = ticks
857-
self._long_axis().set_major_locator(self.locator)
899+
self._locator = ticks
900+
self._long_axis().set_major_locator(self._locator)
858901
self.stale = True
859902

860903
def get_ticks(self, minor=False):
@@ -913,13 +956,12 @@ def minorticks_on(self):
913956
Turn on colorbar minor ticks.
914957
"""
915958
self.ax.minorticks_on()
916-
self.minorlocator = self._long_axis().get_minor_locator()
917959
self._short_axis().set_minor_locator(ticker.NullLocator())
918960

919961
def minorticks_off(self):
920962
"""Turn the minor ticks of the colorbar off."""
921-
self.minorlocator = ticker.NullLocator()
922-
self._long_axis().set_minor_locator(self.minorlocator)
963+
self._minorlocator = ticker.NullLocator()
964+
self._long_axis().set_minor_locator(self._minorlocator)
923965

924966
def set_label(self, label, *, loc=None, **kwargs):
925967
"""
@@ -1157,9 +1199,10 @@ def _reset_locator_formatter_scale(self):
11571199
the mappable normal gets changed: Colorbar.update_normal)
11581200
"""
11591201
self._process_values()
1160-
self.locator = None
1161-
self.minorlocator = None
1162-
self.formatter = None
1202+
self._locator = None
1203+
self._minorlocator = None
1204+
self._formatter = None
1205+
self._minorformatter = None
11631206
if (self.boundaries is not None or
11641207
isinstance(self.norm, colors.BoundaryNorm)):
11651208
if self.spacing == 'uniform':

lib/matplotlib/tests/test_colorbar.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
BoundaryNorm, LogNorm, PowerNorm, Normalize, NoNorm
1212
)
1313
from matplotlib.colorbar import Colorbar
14-
from matplotlib.ticker import FixedLocator
14+
from matplotlib.ticker import FixedLocator, LogFormatter
1515
from matplotlib.testing.decorators import check_figures_equal
1616

1717

@@ -950,3 +950,32 @@ def test_colorbar_no_warning_rcparams_grid_true():
950950
im = ax.pcolormesh([0, 1], [0, 1], [[1]])
951951
# make sure that no warning is raised by fig.colorbar
952952
fig.colorbar(im)
953+
954+
955+
def test_colorbar_set_formatter_locator():
956+
# check that the locator properties echo what is on the axis:
957+
fig, ax = plt.subplots()
958+
pc = ax.pcolormesh(np.random.randn(10, 10))
959+
cb = fig.colorbar(pc)
960+
cb.ax.yaxis.set_major_locator(FixedLocator(np.arange(10)))
961+
cb.ax.yaxis.set_minor_locator(FixedLocator(np.arange(0, 10, 0.2)))
962+
assert cb.locator is cb.ax.yaxis.get_major_locator()
963+
assert cb.minorlocator is cb.ax.yaxis.get_minor_locator()
964+
cb.ax.yaxis.set_major_formatter(LogFormatter())
965+
cb.ax.yaxis.set_minor_formatter(LogFormatter())
966+
assert cb.formatter is cb.ax.yaxis.get_major_formatter()
967+
assert cb.minorformatter is cb.ax.yaxis.get_minor_formatter()
968+
969+
# check that the setter works as expected:
970+
loc = FixedLocator(np.arange(7))
971+
cb.locator = loc
972+
assert cb.ax.yaxis.get_major_locator() is loc
973+
loc = FixedLocator(np.arange(0, 7, 0.1))
974+
cb.minorlocator = loc
975+
assert cb.ax.yaxis.get_minor_locator() is loc
976+
fmt = LogFormatter()
977+
cb.formatter = fmt
978+
assert cb.ax.yaxis.get_major_formatter() is fmt
979+
fmt = LogFormatter()
980+
cb.minorformatter = fmt
981+
assert cb.ax.yaxis.get_minor_formatter() is fmt

0 commit comments

Comments
 (0)
0