8000 FIX: Update the callback in scalar mappable on norm change · matplotlib/matplotlib@ebcbe75 · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ebcbe75

Browse files
committed
FIX: Update the callback in scalar mappable on norm change
When changing a ScalarMappable's norm, the previous norm callback wasn't being removed and updated with the new one. This adds that capability to the norm setter.
1 parent 26977c0 commit ebcbe75

File tree

2 file 8000 s changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

lib/matplotlib/cm.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,16 +257,13 @@ def __init__(self, norm=None, cmap=None):
257257
The colormap used to map normalized data values to RGBA colors.
258258
"""
259259
self._A = None
260-
self.norm = None # So that the setter knows we're initializing.
260+
self._norm = None # So that the setter knows we're initializing.
261261
self.set_norm(norm) # The Normalize instance of this ScalarMappable.
262262
self.cmap = None # So that the setter knows we're initializing.
263263
self.set_cmap(cmap) # The Colormap instance of this ScalarMappable.
264264
#: The last colorbar associated with this ScalarMappable. May be None.
265265
self.colorbar = None
266266
self.callbacksSM = cbook.CallbackRegistry()
267-
# Connect to the Norm's callback
268-
self._id_norm = self.norm.callbacksNorm.connect('changed',
269-
self.changed)
270267

271268
def _scale_norm(self, norm, vmin, vmax):
272269
"""
@@ -436,6 +433,30 @@ def set_cmap(self, cmap):
436433
if not in_init:
437434
self.changed() # Things are not set up properly yet.
438435

436+
@property
437+
def norm(self):
438+
return self._norm
439+
440+
@norm.setter
441+
def norm(self, norm):
442+
_api.check_isinstance((colors.Normalize, None), norm=norm)
443+
if norm is None:
444+
norm = colors.Normalize()
445+
446+
if norm is self.norm:
447+
# We aren't updating anything
448+
return
449+
450+
in_init = self.norm is None
451+
# Remove the current callback and connect to the new one
452+
if not in_init:
453+
self.norm.callbacksNorm.disconnect(self._id_norm)
454+
self._norm = norm
455+
self._id_norm = self.norm.callbacksNorm.connect('changed',
456+
self.changed)
457+
if not in_init:
458+
self.changed()
459+
439460
def set_norm(self, norm):
440461
"""
441462
Set the normalization instance.
@@ -450,13 +471,7 @@ def set_norm(self, norm):
450471
the norm of the mappable will reset the norm, locator, and formatters
451472
on the colorbar to default.
452473
"""
453-
_api.check_isinstance((colors.Normalize, None), norm=norm)
454-
in_init = self.norm is None
455-
if norm is None:
456-
norm = colors.Normalize()
457474
self.norm = norm
458-
if not in_init:
459-
self.changed() # Things are not set up properly yet.
460475

461476
def autoscale(self):
462477
"""

lib/matplotlib/tests/test_colors.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,13 +1427,15 @@ def test_scalarmappable_norm_update():
14271427
norm.clip = True
14281428
assert sm.stale
14291429
# change to the CenteredNorm and TwoSlopeNorm to test those
1430+
# Also make sure that updating the norm directly and with
1431+
# set_norm both update the Norm callback
14301432
norm = mcolors.CenteredNorm()
1431-
sm = matplotlib.cm.ScalarMappable(norm=norm, cmap='plasma')
1433+
sm.norm = norm
14321434
sm.stale = False
14331435
norm.vcenter = 1
14341436
assert sm.stale
14351437
norm = mcolors.TwoSlopeNorm(vcenter=0, vmin=-1, vmax=1)
1436-
sm = matplotlib.cm.ScalarMappable(norm=norm, cmap='plasma')
1438+
sm.set_norm(norm)
14371439
sm.stale = False
14381440
norm.vcenter = 1
14391441
assert sm.stale

0 commit comments

Comments
 (0)
0