Skip to content

Commit

Permalink
Merge c971ecd into 79da3d1
Browse files Browse the repository at this point in the history
  • Loading branch information
astrofrog committed Apr 20, 2018
2 parents 79da3d1 + c971ecd commit ccded2c
Show file tree
Hide file tree
Showing 9 changed files with 289 additions and 34 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Expand Up @@ -128,6 +128,9 @@ v0.13.0 (unreleased)
* Added a mouse over pixel selection tool, which creates a one pixel subset
under the mouse cursor. [#1619]

* Fixed an issue that caused sliders to not be correctly updated when
switching reference data in the image viewer. [#1665]

v0.12.6 (unreleased)
--------------------

Expand Down
2 changes: 1 addition & 1 deletion glue/app/qt/metadata.py
Expand Up @@ -26,7 +26,7 @@ def __init__(self, data, *args, **kwargs):
self.setWindowFlags(Qt.Window | Qt.WindowStaysOnTopHint)

self._text = ""
for name, value in OrderedDict(data.coords.header).items():
for name, value in OrderedDict(data.meta).items():
QtWidgets.QTreeWidgetItem(self.ui.meta_tree.invisibleRootItem(), [name, str(value)])

if data.label:
Expand Down
9 changes: 8 additions & 1 deletion glue/core/component_link.py
Expand Up @@ -355,12 +355,19 @@ def using(self, *args):
attr = 'pixel2world_single_axis' if self.pixel2world else 'world2pixel_single_axis'
func = getattr(self.coords, attr)

# NOTE: in the past, we set any non-specified arguemnts to 0 for the
# input coordinates, but this caused issues because in astropy.wcs
# if one specifies e.g. (0, 0, 3000.) for (ra, dec, velocity), and if
# (0, 0) for RA/Dec would return (nan, nan) normally, the velocity
# is also NaN even though it is decoupled from the other coordinates.
default = self.coords.default_world_coords(self.ndim)

args2 = [None] * self.ndim
for f, a in zip(self.from_needed, args):
args2[f] = a
for i in range(self.ndim):
if args2[i] is None:
args2[i] = np.zeros_like(args[0])
args2[i] = np.ones_like(args[0]) * default[self.ndim - 1 - i]
args2 = tuple(args2)

return func(*args2[::-1], axis=self.ndim - 1 - self.index)
Expand Down
25 changes: 23 additions & 2 deletions glue/core/coordinates.py
Expand Up @@ -51,6 +51,9 @@ def world2pixel(self, *args):
"""
return args

def default_world_coords(self, ndim):
return np.zeros(ndim, dtype=float)

# PY3: pixel2world_single_axis(self, *pixel, axis=None)

def pixel2world_single_axis(self, *pixel, **kwargs):
Expand Down Expand Up @@ -81,6 +84,9 @@ def pixel2world_single_axis(self, *pixel, **kwargs):
if axis is None:
raise ValueError("axis needs to be set")

if np.size(pixel[0]) == 0:
return np.array([], dtype=float)

original_shape = pixel[0].shape
pixel_new = []
dep_axes = self.dependent_axes(axis)
Expand Down Expand Up @@ -123,6 +129,9 @@ def world2pixel_single_axis(self, *world, **kwargs):
if axis is None:
raise ValueError("axis needs to be set")

if np.size(world[0]) == 0:
return np.array([], dtype=float)

original_shape = world[0].shape
world_new = []
dep_axes = self.dependent_axes(axis)
Expand Down Expand Up @@ -282,11 +291,23 @@ def __setstate__(self, state):

def pixel2world(self, *pixel):
# PY3: can just do pix2world(*pixel, 0)
return self._wcs.wcs_pix2world(*(tuple(pixel) + (0,)))
if np.size(pixel[0]) == 0:
return tuple(np.array([], dtype=float) for p in pixel)
else:
return self._wcs.wcs_pix2world(*(tuple(pixel) + (0,)))

def world2pixel(self, *world):
# PY3: can just do world2pix(*world, 0)
return self._wcs.wcs_world2pix(*(tuple(world) + (0,)))
if np.size(world[0]) == 0:
return tuple(np.array([], dtype=float) for w in world)
else:
return self._wcs.wcs_world2pix(*(tuple(world) + (0,)))

def default_world_coords(self, ndim):
if ndim != self._wcs.naxis:
raise ValueError("Requested default world coordinates for {0} "
"dimensions, WCS has {1}".format(ndim, self._wcs.naxis))
return self._wcs.wcs.crval

def axis_label(self, axis):
header = self._header
Expand Down
Binary file added glue/icons/glue_crosshair.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
200 changes: 200 additions & 0 deletions glue/icons/glue_crosshair.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 35 additions & 8 deletions glue/viewers/image/layer_artist.py
Expand Up @@ -9,6 +9,7 @@

from glue.viewers.image.state import ImageLayerState, ImageSubsetLayerState
from glue.viewers.image.python_export import python_export_image_layer, python_export_image_subset_layer
from glue.viewers.image.pixel_selection_mode import PixelSubsetState
from glue.viewers.matplotlib.layer_artist import MatplotlibLayerArtist
from glue.core.exceptions import IncompatibleAttribute
from glue.utils import color2rgb
Expand All @@ -19,6 +20,7 @@
from glue.external.modest_image import imshow



class BaseImageLayerArtist(MatplotlibLayerArtist, HubListener):

def __init__(self, axes, viewer_state, layer_state=None, layer=None):
Expand Down Expand Up @@ -276,19 +278,45 @@ def __init__(self, axes, viewer_state, layer_state=None, layer=None):
self.image_artist = imshow(self.axes, self.subset_array,
origin='lower', interpolation='nearest',
vmin=0, vmax=1, aspect=self._viewer_state.aspect)
self.mpl_artists = [self.image_artist]

self._line_x = self.axes.axvline(0)
self._line_x.set_visible(False)

self._line_y = self.axes.axhline(0)
self._line_y.set_visible(False)

self.mpl_artists = [self.image_artist, self._line_x, self._line_y]

@defer_draw
def _update_data(self):
if isinstance(self.state.layer.subset_state, PixelSubsetState):
slices = self.state.layer.subset_state.slices
x = slices[self._viewer_state.x_att.axis].start
y = slices[self._viewer_state.y_att.axis].start
self._line_x.set_data([x, x], [0, 1])
self._line_x.set_visible(True)
self._line_y.set_data([0, 1], [y, y])
self._line_y.set_visible(True)
else:
self._line_x.set_visible(False)
self._line_y.set_visible(False)
self.image_artist.invalidate_cache()
self.redraw() # forces subset to be recomputed

@defer_draw
def _update_visual_attributes(self):

if not self.enabled:
return

# TODO: deal with color using a colormap instead of having to change data

self.image_artist.set_visible(self.state.visible)
self.image_artist.set_zorder(self.state.zorder)
self.image_artist.set_alpha(self.state.alpha)
for artist in self.mpl_artists:
if artist is self.image_artist:
artist.set_visible(self.state.visible)
artist.set_alpha(self.state.alpha)
else:
artist.set_color(self.state.color)
artist.set_alpha(self.state.alpha * 0.5)
artist.set_zorder(self.state.zorder)

self.redraw()

Expand Down Expand Up @@ -321,8 +349,7 @@ def _update_image(self, force=False, **kwargs):

if force or any(prop in changed for prop in ('layer', 'attribute', 'color',
'x_att', 'y_att', 'slices')):
self.image_artist.invalidate_cache()
self.redraw() # forces subset to be recomputed
self._update_data()
force = True # make sure scaling and visual attributes are updated

if force or any(prop in changed for prop in ('zorder', 'visible', 'alpha')):
Expand Down

0 comments on commit ccded2c

Please sign in to comment.