Skip to content

Commit

Permalink
Make sure clips properly autoapplied
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Beaumont committed Aug 7, 2014
1 parent ea85572 commit bdcc8f0
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 40 deletions.
41 changes: 19 additions & 22 deletions Examples.ipynb

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,24 @@ See the [example notebook](http://nbviewer.ipython.org/github/glue-viz/ds9norm/b

data = fits.getdata('M51.fits')
norm = DS9Normalize(bias=0.2)
figure, axs = plt.subplots(ncols=3, nrows=3, squeeze=False, tight_layout=True)

for ax, bias in zip(axs[2], [.2, .5, .8]):
ax.imshow(data, norm=DS9Normalize(bias=bias))
ax.set_title('Bias = %0.1f' % bias)
figure, axs = plt.subplots(ncols=4, nrows=4, squeeze=False, tight_layout=True)

for ax, stretch in zip(axs[0], ['linear', 'sqrt', 'arcsinh', 'log']):
ax.imshow(data, norm=DS9Normalize(stretch=stretch))
ax.set_title(stretch)

for ax, contrast in zip(axs[1], [0.5, 1, 2]):
for ax, contrast in zip(axs[1], [0.5, 1, 2, -1]):
ax.imshow(data, norm=DS9Normalize(contrast=contrast))
ax.set_title('Contrast = %0.1f' % contrast)

for ax, stretch in zip(axs[0], ['linear', 'sqrt', 'arcsinh']):
ax.imshow(data, norm=DS9Normalize(stretch=stretch))
ax.set_title(stretch)
for ax, bias in zip(axs[2], [.2, .5, .8, .9]):
ax.imshow(data, norm=DS9Normalize(bias=bias))
ax.set_title('Bias = %0.1f' % bias)

for ax, (lo, hi) in zip(axs[3], [(0, 100), (1, 99), (5, 95), (10, 90)]):
im = ax.imshow(data, norm=DS9Normalize(clip_lo=lo, clip_hi=hi))
ax.set_title('%i-%i%%' % (lo, hi))
```

![ds9norm demo](gallery.png)
Expand Down
39 changes: 31 additions & 8 deletions ds9norm.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ def asinh_warp(x, vmin, vmax, bias, contrast):
# for mpl <= 1.1, Normalize is an old-style class
# explicitly inheriting from object allows property to work
class DS9Normalize(Normalize, object):

"""
A Matplotlib Normalize object that implements DS9's image stretching
Expand All @@ -145,10 +146,10 @@ class DS9Normalize(Normalize, object):
Which stretch function to use. Defaults to 'linear'
clip_lo : number
Where to clip the minimum image intensity. Expressed as a percentile
of the range of intensity values. Defaults to 5
of the range of intensity values. Defaults to 0
clip_hi : number
Where to clip the maximum image intensity. Expressed as a percentile
of the range of intensity values. Defaults to 95
of the range of intensity values. Defaults to 100
bias : float
The location of the middle-grey value,
relative to the [clip_lo, clip_hi] range. Defaults to 0.5
Expand All @@ -159,14 +160,32 @@ class DS9Normalize(Normalize, object):

def __init__(self, stretch='linear',
bias=0.5, contrast=1.0,
clip_lo=5., clip_hi=95.):
clip_lo=0., clip_hi=100.):
super(DS9Normalize, self).__init__()
self.stretch = stretch
self.bias = bias
self.contrast = contrast
self.clip_lo = clip_lo
self.clip_hi = clip_hi

@property
def clip_lo(self):
return self._clip_lo

@clip_lo.setter
def clip_lo(self, value):
self._clip_lo = value
self.vmin = self.vmax = None

@property
def clip_hi(self):
return self._clip_hi

@clip_hi.setter
def clip_hi(self, value):
self._clip_hi = value
self.vmin = self.vmax = None

@property
def stretch(self):
return self._stretch
Expand All @@ -178,15 +197,19 @@ def stretch(self, value):
(value, warpers.keys()))
self._stretch = value

def autoscale(self, A):
self.update_clip(A)

def autoscale_None(self, A):
if self.vmin is None or self.vmax is None:
self.update_clip(A)

def update_clip(self, image):
vmin, vmax = fast_limits(image, self.clip_lo, self.clip_hi)
self.vmin = vmin
self.vmax = vmax
self.vmin, self.vmax = fast_limits(image, self.clip_lo, self.clip_hi)

def __call__(self, value, clip=False):
# XXX ignore clip
self.autoscale_None(value)

self.autoscale_None(value) # set vmin, vmax if unset
inverted = self.vmax <= self.vmin

hi, lo = max(self.vmin, self.vmax), min(self.vmin, self.vmax)
Expand Down
Binary file modified gallery.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 10 additions & 2 deletions test_ds9norm.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,16 @@ def test_invalid_stretch(self):
def test_update_clip(self):
x = np.arange(101)
self.norm.update_clip(x)
assert self.norm.vmin == 5
assert self.norm.vmax == 95
assert self.norm.vmin == 0
assert self.norm.vmax == 100

def test_autoscale_on_call(self):
x = np.arange(101)
self.norm.clip_lo = 7
self.norm.clip_hi = 16
self.norm(x)
np.testing.assert_array_almost_equal([self.norm.vmin, self.norm.vmax],
[7, 16])

def test_update_clip_nans(self):
x = np.zeros(5) * np.nan
Expand Down

0 comments on commit bdcc8f0

Please sign in to comment.