Skip to content

Navigation Menu

Sign in
Appearance settings

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 c948ea5

Browse filesBrowse files
NelleVefiring
authored andcommitted
Backport PR #14295: Fix bug in SymmetricalLogTransform.
1 parent a8018e8 commit c948ea5
Copy full SHA for c948ea5

File tree

Expand file treeCollapse file tree

2 files changed

+47
-24
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+47
-24
lines changed

‎lib/matplotlib/scale.py

Copy file name to clipboardExpand all lines: lib/matplotlib/scale.py
+16-22Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -486,18 +486,14 @@ def __init__(self, base, linthresh, linscale):
486486
self._log_base = np.log(base)
487487

488488
def transform_non_affine(self, a):
489-
sign = np.sign(a)
490-
masked = ma.masked_inside(a,
491-
-self.linthresh,
492-
self.linthresh,
493-
copy=False)
494-
log = sign * self.linthresh * (
495-
self._linscale_adj +
496-
ma.log(np.abs(masked) / self.linthresh) / self._log_base)
497-
if masked.mask.any():
498-
return ma.where(masked.mask, a * self._linscale_adj, log)
499-
else:
500-
return log
489+
abs_a = np.abs(a)
490+
with np.errstate(divide="ignore", invalid="ignore"):
491+
out = np.sign(a) * self.linthresh * (
492+
self._linscale_adj +
493+
np.log(abs_a / self.linthresh) / self._log_base)
494+
inside = abs_a <= self.linthresh
495+
out[inside] = a[inside] * self._linscale_adj
496+
return out
501497

502498
def inverted(self):
503499
return InvertedSymmetricalLogTransform(self.base, self.linthresh,
@@ -520,16 +516,14 @@ def __init__(self, base, linthresh, linscale):
520516
self._linscale_adj = (linscale / (1.0 - self.base ** -1))
521517

522518
def transform_non_affine(self, a):
523-
sign = np.sign(a)
524-
masked = ma.masked_inside(a, -self.invlinthresh,
525-
self.invlinthresh, copy=False)
526-
exp = sign * self.linthresh * (
527-
ma.power(self.base, (sign * (masked / self.linthresh))
528-
- self._linscale_adj))
529-
if masked.mask.any():
530-
return ma.where(masked.mask, a / self._linscale_adj, exp)
531-
else:
532-
return exp
519+
abs_a = np.abs(a)
520+
with np.errstate(divide="ignore", invalid="ignore"):
521+
out = np.sign(a) * self.linthresh * (
522+
np.power(self.base,
523+
abs_a / self.linthresh - self._linscale_adj))
524+
inside = abs_a <= self.invlinthresh
525+
out[inside] = a[inside] / self._linscale_adj
526+
return out
533527

534528
def inverted(self):
535529
return SymmetricalLogTransform(self.base,

‎lib/matplotlib/tests/test_scale.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_scale.py
+31-2Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
from matplotlib.testing.decorators import check_figures_equal, image_comparison
21
import matplotlib.pyplot as plt
3-
from matplotlib.scale import Log10Transform, InvertedLog10Transform
2+
from matplotlib.scale import (Log10Transform, InvertedLog10Transform,
3+
SymmetricalLogTransform)
4+
from matplotlib.testing.decorators import check_figures_equal, image_comparison
45

56
import numpy as np
7+
from numpy.testing import assert_allclose
68
import io
79
import platform
810
import pytest
@@ -21,6 +23,33 @@ def test_log_scales(fig_test, fig_ref):
2123
ax_ref.plot(xlim, [24.1, 24.1], 'b')
2224

2325

26+
def test_symlog_mask_nan():
27+
# Use a transform round-trip to verify that the forward and inverse
28+
# transforms work, and that they respect nans and/or masking.
29+
slt = SymmetricalLogTransform(10, 2, 1)
30+
slti = slt.inverted()
31+
32+
x = np.arange(-1.5, 5, 0.5)
33+
out = slti.transform_non_affine(slt.transform_non_affine(x))
34+
assert_allclose(out, x)
35+
assert type(out) == type(x)
36+
37+
x[4] = np.nan
38+
out = slti.transform_non_affine(slt.transform_non_affine(x))
39+
assert_allclose(out, x)
40+
assert type(out) == type(x)
41+
42+
x = np.ma.array(x)
43+
out = slti.transform_non_affine(slt.transform_non_affine(x))
44+
assert_allclose(out, x)
45+
assert type(out) == type(x)
46+
47+
x[3] = np.ma.masked
48+
out = slti.transform_non_affine(slt.transform_non_affine(x))
49+
assert_allclose(out, x)
50+
assert type(out) == type(x)
51+
52+
2453
@image_comparison(baseline_images=['logit_scales'], remove_text=True,
2554
extensions=['png'])
2655
def test_logit_scales():

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.