Skip to content

Commit

Permalink
Merge pull request #4154 from clemisch/main
Browse files Browse the repository at this point in the history
The added tests pass (except on PySide6 which is another issue), so it's good for me!

Thanks for the contribution!
  • Loading branch information
t20100 authored Oct 7, 2024
2 parents 1191989 + c88921e commit 68c65f1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/silx/gui/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,10 @@ class Colormap(qt.QObject):
"""constant for autoscale using mean +/- 3*std(data)
with a clamp on min/max of the data"""

AUTOSCALE_MODES = (MINMAX, STDDEV3)
PERCENTILE_1_99 = "percentile_1_99"
"""constant for autoscale using 1st and 99th percentile of data"""

AUTOSCALE_MODES = (MINMAX, STDDEV3, PERCENTILE_1_99)
"""Tuple of managed auto scale algorithms"""

sigChanged = qt.Signal()
Expand Down
1 change: 1 addition & 0 deletions src/silx/gui/dialog/ColormapDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ class _AutoscaleModeComboBox(qt.QComboBox):
DATA = {
Colormap.MINMAX: ("Min/max", "Use the data min/max"),
Colormap.STDDEV3: ("Mean±3std", "Use the data mean ± 3 × standard deviation"),
Colormap.PERCENTILE_1_99: ("Percentile 1-99", "Use 1st to 99th percentile of data"),
}

def __init__(self, parent: qt.QWidget):
Expand Down
29 changes: 29 additions & 0 deletions src/silx/gui/test/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ def testAutoscaleMode(self):
self.assertEqual(colormap.getAutoscaleMode(), Colormap.STDDEV3)
colormap.setAutoscaleMode(Colormap.MINMAX)
self.assertEqual(colormap.getAutoscaleMode(), Colormap.MINMAX)
colormap.setAutoscaleMode(Colormap.PERCENTILE_1_99)
self.assertEqual(colormap.getAutoscaleMode(), Colormap.PERCENTILE_1_99)

def testStoreRestore(self):
colormaps = [Colormap(name="viridis"), Colormap(normalization=Colormap.SQRT)]
Expand Down Expand Up @@ -592,6 +594,8 @@ def testAutoscaleRange(self):
),
(Colormap.LINEAR, Colormap.STDDEV3, numpy.array([10, 100]), (10, 100)),
(Colormap.LOGARITHM, Colormap.STDDEV3, numpy.array([10, 100]), (10, 100)),
(Colormap.LINEAR, Colormap.PERCENTILE_1_99, numpy.array([10, 100]), (10.9, 99.1)),
(Colormap.LOGARITHM, Colormap.PERCENTILE_1_99, numpy.array([10, 100]), (10.9, 99.1)),
# With nan
(
Colormap.LINEAR,
Expand All @@ -617,6 +621,18 @@ def testAutoscaleRange(self):
data_std_inside_nan,
(1, 1.6733506885453602),
),
(
Colormap.LINEAR,
Colormap.PERCENTILE_1_99,
numpy.array([10, 20, 50, nan]),
(10.2, 49.4),
),
(
Colormap.LOGARITHM,
Colormap.PERCENTILE_1_99,
numpy.array([10, 50, 100, nan]),
(10.8, 99.),
),
# With negative
(
Colormap.LOGARITHM,
Expand All @@ -630,6 +646,19 @@ def testAutoscaleRange(self):
numpy.array([10, 100, -10]),
(10, 100),
),
(
Colormap.LOGARITHM,
Colormap.PERCENTILE_1_99,
numpy.array([10, 50, 100, -50]),
(10.8, 99.),
),
# With inf
(
Colormap.LOGARITHM,
Colormap.PERCENTILE_1_99,
numpy.array([10, 50, 100, float("inf")]),
(10.8, 99.),
),
]
for norm, mode, array, expectedRange in data:
with self.subTest(norm=norm, mode=mode, array=array):
Expand Down
11 changes: 11 additions & 0 deletions src/silx/math/colormap.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ def autoscale(self, data, mode):
vmax = dmax
else:
vmax = min(dmax, stdmax)
elif mode == "percentile_1_99":
vmin, vmax = self.autoscale_percentile_1_99(data)

else:
raise ValueError("Unsupported mode: %s" % mode)
Expand Down Expand Up @@ -319,6 +321,15 @@ def autoscale_mean3std(self, data):
mean + 3 * std, 0.0, 1.0
)

def autoscale_percentile_1_99(self, data):
"""Autoscale using [1st, 99th] percentiles"""
data = data[self.is_valid(data)]
if data.dtype.kind == "f": # Strip +/-inf
data = data[numpy.isfinite(data)]
if data.size == 0:
return None, None
return numpy.nanpercentile(data, (1, 99))


class _LinearNormalizationMixIn(_NormalizationMixIn):
"""Colormap normalization mix-in class specific to autoscale taken from initial range"""
Expand Down

0 comments on commit 68c65f1

Please sign in to comment.