def test_sliced_ND_input(wcs_4d, sub_wcs, wcs_slice, plt_close): slices_wcsaxes = [0, 'x', 'y'] for sub_wcs in (sub_wcs, SlicedLowLevelWCS(wcs_4d, wcs_slice)): with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=FutureWarning) _, coord_meta = transform_coord_meta_from_wcs( sub_wcs, RectangularFrame, slices=slices_wcsaxes) assert all(len(x) == 3 for x in coord_meta.values()) assert coord_meta['name'] == [ 'time', ('custom:pos.helioprojective.lat', 'hplt-tan', 'hplt'), ('custom:pos.helioprojective.lon', 'hpln-tan', 'hpln') ] assert coord_meta['type'] == ['scalar', 'latitude', 'longitude'] assert coord_meta['wrap'] == [None, None, 180.0] assert coord_meta['unit'] == [ u.Unit("min"), u.Unit("deg"), u.Unit("deg") ] assert coord_meta['visible'] == [False, True, True] assert coord_meta['format_unit'] == [ u.Unit("min"), u.Unit("arcsec"), u.Unit("arcsec") ] assert coord_meta['default_axislabel_position'] == ['', 'b', 'l'] assert coord_meta['default_ticklabel_position'] == ['', 'b', 'l'] assert coord_meta['default_ticks_position'] == ['', 'bltr', 'bltr'] # Validate the axes initialize correctly plt.subplot(projection=sub_wcs, slices=slices_wcsaxes)
def apply_slices(wcs, slices): """ Take the input WCS and slices and return a sliced WCS for the transform and a mapping of world axes in the sliced WCS to the input WCS. """ if isinstance(wcs, SlicedLowLevelWCS): world_keep = list(wcs._world_keep) else: world_keep = list(range(wcs.world_n_dim)) # world_map is the index of the world axis in the input WCS for a given # axis in the transform_wcs world_map = list(range(wcs.world_n_dim)) transform_wcs = wcs invert_xy = False if slices is not None: wcs_slice = list(slices) wcs_slice[wcs_slice.index("x")] = slice(None) if 'y' in slices: wcs_slice[wcs_slice.index("y")] = slice(None) invert_xy = slices.index('x') > slices.index('y') transform_wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1]) world_map = tuple( world_keep.index(i) for i in transform_wcs._world_keep) return transform_wcs, invert_xy, world_map
def test_wcs_type_transform_regression(): wcs = WCS(TARGET_HEADER) sliced_wcs = SlicedLowLevelWCS(wcs, np.s_[1:-1, 1:-1]) ax = plt.subplot(1, 1, 1, projection=wcs) ax.get_transform(sliced_wcs) high_wcs = HighLevelWCSWrapper(sliced_wcs) ax.get_transform(sliced_wcs)
def _slice_wcs(self, item): if self.wcs is None: return None try: llwcs = SlicedLowLevelWCS(self.wcs.low_level_wcs, item) return HighLevelWCSWrapper(llwcs) except Exception as err: self._handle_wcs_slicing_error(err, item)
def test_nddata_wcs_setter_with_low_level_wcs(): ndd = NDData(np.ones((5, 5))) wcs = WCS() # If the wcs property is set with a low level WCS it should get # wrapped to high level. low_level = SlicedLowLevelWCS(wcs, 5) assert not isinstance(low_level, BaseHighLevelWCS) ndd.wcs = low_level assert isinstance(ndd.wcs, BaseHighLevelWCS)
def __init__(self, original_data, indices): super(IndexedData, self).__init__() if len(indices) != original_data.ndim: raise ValueError("The 'indices' tuple should have length {0}" .format(original_data.ndim)) if hasattr(original_data, 'coords'): if original_data.coords is None: self._coords = None else: slices = [slice(None) if idx is None else idx for idx in indices] self._coords = SlicedLowLevelWCS(original_data.coords, slices) self._original_data = original_data self._cid_to_original_cid = {} self._original_cid_to_cid = {} self.indices = indices
def _stokes_slice(self, stokes_ix, normalize=False): """Return a 3D NDCube (wavelength, coord1, coord2) for a given Stokes parameter""" # Construct the WCS object for the smaller 3D cube. # This function should only called if the d_sh = self.data.shape wcs_slice = [0] * self.wcs.pixel_n_dim wcs_slice[0] = stokes_ix wcs_slice[1] = slice(0, d_sh[1]) wcs_slice[2] = slice(0, d_sh[2]) wcs_slice[3] = slice(0, d_sh[3]) #print(wcs_slice) wcs_slice = SlicedLowLevelWCS(self.wcs.low_level_wcs, wcs_slice) #newcube = StokesParamCube(self.data[stokes_ix,:,:,:], HighLevelWCSWrapper(wcs_slice), self._stokes_axis[stokes_ix]) #cube_meta = {'stokes': self._stokes_axis[stokes_ix]} cube_meta = self.meta.copy() cube_meta['stokes'] = self._stokes_axis[stokes_ix] newcube = StokesParamCube(self.data[stokes_ix, :, :, :], HighLevelWCSWrapper(wcs_slice), meta=cube_meta) # Normalize the spectra if wanted. if stokes_ix != 0: if self.normalize is True: # Normalize by I I = self._stokes_slice(0) newcube = StokesParamCube(newcube.data / I.data, newcube.wcs, self._stokes_axis[stokes_ix], meta=newcube.meta) elif self.normalize: # normalize by non-zero float # TODO: sanity check input newcube = StokesParamCube(newcube.data / self.normalize, newcube.wcs, self._stokes_axis[stokes_ix], meta=newcube.meta) #newcube.meta = {'stokes': self._stokes_axis[stokes_ix]} return newcube
def sub_wcs(wcs_4d, wcs_slice): return SlicedLowLevelWCS(wcs_4d, wcs_slice)
def get_crop_item_from_points(points, wcs, crop_by_values): """ Find slice item that crops to minimum cube in array-space containing specified world points. Parameters ---------- points : iterable of iterables Each iterable represents a point in real world space. Each element in a point gives the real world coordinate value of the point in high-level coordinate objects or quantities. (Must be consistenly high or low level within and across points.) Objects must be in the order required by wcs.world_to_array_index/world_to_array_index_values. wcs : `~astropy.wcs.wcsapi.BaseHighLevelWCS`, `~astropy.wcs.wcsapi.BaseLowLevelWCS` The WCS to use to convert the world coordinates to array indices. crop_by_values : `bool` Denotes whether cropping is done using high-level objects or "values", i.e. low-level objects. Returns ------- item : `tuple` of `slice` The slice item for each axis of the cube which, when applied to the cube, will return the minimum cube in array-index-space that contains all the input world points. """ # Define a list of lists to hold the array indices of the points # where each inner list gives the index of all points for that array axis. combined_points_array_idx = [[]] * wcs.pixel_n_dim # For each point compute the corresponding array indices. for point in points: # Get the arrays axes associated with each element in point. if crop_by_values: point_inputs_array_axes = [] for i in range(wcs.world_n_dim): pix_axes = np.array( wcs_utils.world_axis_to_pixel_axes( i, wcs.axis_correlation_matrix)) point_inputs_array_axes.append( tuple( wcs_utils.convert_between_array_and_pixel_axes( pix_axes, wcs.pixel_n_dim))) point_inputs_array_axes = tuple(point_inputs_array_axes) else: point_inputs_array_axes = wcs_utils.array_indices_for_world_objects( HighLevelWCSWrapper(wcs)) # Get indices of array axes which correspond to only None inputs in point # as well as those that correspond to a coord. point_indices_with_inputs = [] array_axes_with_input = [] for i, coord in enumerate(point): if coord is not None: point_indices_with_inputs.append(i) array_axes_with_input.append(point_inputs_array_axes[i]) array_axes_with_input = set(chain.from_iterable(array_axes_with_input)) array_axes_without_input = set(range( wcs.pixel_n_dim)) - array_axes_with_input # Slice out the axes that do not correspond to a coord # from the WCS and the input point. wcs_slice = np.array([slice(None)] * wcs.pixel_n_dim) if len(array_axes_without_input): wcs_slice[np.array(list(array_axes_without_input))] = 0 sliced_wcs = SlicedLowLevelWCS(wcs, slices=tuple(wcs_slice)) sliced_point = np.array( point, dtype=object)[np.array(point_indices_with_inputs)] # Derive the array indices of the input point and place each index # in the list corresponding to its axis. if crop_by_values: point_array_indices = sliced_wcs.world_to_array_index_values( *sliced_point) # If returned value is a 0-d array, convert to a length-1 tuple. if isinstance(point_array_indices, np.ndarray) and point_array_indices.ndim == 0: point_array_indices = (point_array_indices.item(), ) else: # Convert from scalar arrays to scalars point_array_indices = tuple(a.item() for a in point_array_indices) else: point_array_indices = HighLevelWCSWrapper( sliced_wcs).world_to_array_index(*sliced_point) # If returned value is a 0-d array, convert to a length-1 tuple. if isinstance(point_array_indices, np.ndarray) and point_array_indices.ndim == 0: point_array_indices = (point_array_indices.item(), ) for axis, index in zip(array_axes_with_input, point_array_indices): combined_points_array_idx[ axis] = combined_points_array_idx[axis] + [index] # Define slice item with which to slice cube. item = [] result_is_scalar = True for axis_indices in combined_points_array_idx: if axis_indices == []: result_is_scalar = False item.append(slice(None)) else: min_idx = min(axis_indices) max_idx = max(axis_indices) + 1 if max_idx - min_idx == 1: item.append(min_idx) else: item.append(slice(min_idx, max_idx)) result_is_scalar = False # If item will result in a scalar cube, raise an error as this is not currently supported. if result_is_scalar: raise ValueError( "Input points causes cube to be cropped to a single pixel. " "This is not supported.") return tuple(item)
def as_high_level_wcs(wcs): return HighLevelWCSWrapper(SlicedLowLevelWCS(wcs, Ellipsis))
def __init__(self, data1=None, data2=None, cids1=None, cids2=None): wcs1, wcs2 = data1.coords, data2.coords forwards = backwards = None if wcs1.pixel_n_dim == wcs2.pixel_n_dim and wcs1.world_n_dim == wcs2.world_n_dim: if (wcs1.world_axis_physical_types.count(None) == 0 and wcs2.world_axis_physical_types.count(None) == 0): # The easiest way to check if the WCSes are compatible is to simply try and # see if values can be transformed for a single pixel. In future we might # find that this requires optimization performance-wise, but for now let's # not do premature optimization. pixel_cids1, pixel_cids2, forwards, backwards = get_cids_and_functions( wcs1, wcs2, data1.pixel_component_ids[::-1], data2.pixel_component_ids[::-1]) self._physical_types_1 = wcs1.world_axis_physical_types self._physical_types_2 = wcs2.world_axis_physical_types if not forwards or not backwards: # A generalized APE 14-compatible way # Handle also the extra-spatial axes such as those of the time and wavelength dimensions wcs1_celestial_physical_types = wcs2_celestial_physical_types = [] slicing_axes1 = slicing_axes2 = [] cids1 = data1.pixel_component_ids cids2 = data2.pixel_component_ids if wcs1.has_celestial and wcs2.has_celestial: wcs1_celestial_physical_types = wcs1.celestial.world_axis_physical_types wcs2_celestial_physical_types = wcs2.celestial.world_axis_physical_types cids1_celestial = [ cids1[wcs1.wcs.naxis - wcs1.wcs.lng - 1], cids1[wcs1.wcs.naxis - wcs1.wcs.lat - 1] ] cids2_celestial = [ cids2[wcs2.wcs.naxis - wcs2.wcs.lng - 1], cids2[wcs2.wcs.naxis - wcs2.wcs.lat - 1] ] if wcs1.celestial.wcs.lng > wcs1.celestial.wcs.lat: cids1_celestial = cids1_celestial[::-1] if wcs2.celestial.wcs.lng > wcs2.celestial.wcs.lat: cids2_celestial = cids2_celestial[::-1] slicing_axes1 = [ cids1_celestial[0].axis, cids1_celestial[1].axis ] slicing_axes2 = [ cids2_celestial[0].axis, cids2_celestial[1].axis ] wcs1_sliced_physical_types = wcs2_sliced_physical_types = [] if wcs1_celestial_physical_types is not None: wcs1_sliced_physical_types = wcs1_celestial_physical_types if wcs2_celestial_physical_types is not None: wcs2_sliced_physical_types = wcs2_celestial_physical_types for i, physical_type1 in enumerate(wcs1.world_axis_physical_types): for j, physical_type2 in enumerate( wcs2.world_axis_physical_types): if physical_type1 == physical_type2: if physical_type1 not in wcs1_sliced_physical_types: slicing_axes1.append(wcs1.world_n_dim - i - 1) wcs1_sliced_physical_types.append(physical_type1) if physical_type2 not in wcs2_sliced_physical_types: slicing_axes2.append(wcs2.world_n_dim - j - 1) wcs2_sliced_physical_types.append(physical_type2) slicing_axes1 = sorted(slicing_axes1, key=str, reverse=True) slicing_axes2 = sorted(slicing_axes2, key=str, reverse=True) # Generate slices for the wcs slicing slices1 = [slice(None)] * wcs1.world_n_dim slices2 = [slice(None)] * wcs2.world_n_dim for i in range(wcs1.world_n_dim): if i not in slicing_axes1: slices1[i] = 0 for j in range(wcs2.world_n_dim): if j not in slicing_axes2: slices2[j] = 0 wcs1_sliced = SlicedLowLevelWCS(wcs1, tuple(slices1)) wcs2_sliced = SlicedLowLevelWCS(wcs2, tuple(slices2)) wcs1_final = HighLevelWCSWrapper(copy.copy(wcs1_sliced)) wcs2_final = HighLevelWCSWrapper(copy.copy(wcs2_sliced)) cids1_sliced = [cids1[x] for x in slicing_axes1] cids1_sliced = sorted(cids1_sliced, key=str, reverse=True) cids2_sliced = [cids2[x] for x in slicing_axes2] cids2_sliced = sorted(cids2_sliced, key=str, reverse=True) pixel_cids1, pixel_cids2, forwards, backwards = get_cids_and_functions( wcs1_final, wcs2_final, cids1_sliced, cids2_sliced) self._physical_types_1 = wcs1_sliced_physical_types self._physical_types_2 = wcs2_sliced_physical_types if pixel_cids1 is None: raise IncompatibleWCS( "Can't create WCS link between {0} and {1}".format( data1.label, data2.label)) super(WCSLink, self).__init__(pixel_cids1, pixel_cids2, forwards=forwards, backwards=backwards) self.data1 = data1 self.data2 = data2
def transform_coord_meta_from_wcs(wcs, frame_class, slices=None): if slices is not None: slices = tuple(slices) if wcs.pixel_n_dim > 2: if slices is None: raise ValueError("WCS has more than 2 pixel dimensions, so " "'slices' should be set") elif len(slices) != wcs.pixel_n_dim: raise ValueError("'slices' should have as many elements as WCS " "has pixel dimensions (should be {})".format( wcs.pixel_n_dim)) is_fits_wcs = isinstance(wcs, WCS) coord_meta = {} coord_meta['name'] = [] coord_meta['type'] = [] coord_meta['wrap'] = [] coord_meta['unit'] = [] coord_meta['visible'] = [] coord_meta['format_unit'] = [] for idx in range(wcs.world_n_dim): axis_type = wcs.world_axis_physical_types[idx] axis_unit = u.Unit(wcs.world_axis_units[idx]) coord_wrap = None format_unit = axis_unit coord_type = 'scalar' if axis_type is not None: axis_type_split = axis_type.split('.') if "pos.helioprojective.lon" in axis_type: coord_wrap = 180. format_unit = u.arcsec coord_type = "longitude" elif "pos.helioprojective.lat" in axis_type: format_unit = u.arcsec coord_type = "latitude" elif "pos.heliographic.stonyhurst.lon" in axis_type: coord_wrap = 180. format_unit = u.arcsec coord_type = "longitude" elif "pos.heliographic.stonyhurst.lat" in axis_type: format_unit = u.arcsec coord_type = "latitude" elif "pos.heliographic.carrington.lon" in axis_type: coord_wrap = 360. format_unit = u.arcsec coord_type = "longitude" elif "pos.heliographic.carrington.lat" in axis_type: format_unit = u.arcsec coord_type = "latitude" elif "pos" in axis_type_split: if "lon" in axis_type_split: coord_type = "longitude" elif "lat" in axis_type_split: coord_type = "latitude" elif "ra" in axis_type_split: coord_type = "longitude" format_unit = u.hourangle elif "dec" in axis_type_split: coord_type = "latitude" elif "alt" in axis_type_split: coord_type = "longitude" elif "az" in axis_type_split: coord_type = "latitude" elif "long" in axis_type_split: coord_type = "longitude" coord_meta['type'].append(coord_type) coord_meta['wrap'].append(coord_wrap) coord_meta['format_unit'].append(format_unit) coord_meta['unit'].append(axis_unit) # For FITS-WCS, for backward-compatibility, we need to make sure that we # provide aliases based on CTYPE for the name. if is_fits_wcs: if isinstance(wcs, WCS): alias = wcs.wcs.ctype[idx][:4].replace('-', '').lower() elif isinstance(wcs, SlicedLowLevelWCS): alias = wcs._wcs.wcs.ctype[wcs._world_keep[idx]][:4].replace( '-', '').lower() name = (axis_type, alias) if axis_type else alias else: name = axis_type or '' coord_meta['name'].append(name) coord_meta['default_axislabel_position'] = [''] * wcs.world_n_dim coord_meta['default_ticklabel_position'] = [''] * wcs.world_n_dim coord_meta['default_ticks_position'] = [''] * wcs.world_n_dim invert_xy = False if slices is not None: wcs_slice = list(slices) wcs_slice[wcs_slice.index("x")] = slice(None) if 'y' in slices: wcs_slice[wcs_slice.index("y")] = slice(None) invert_xy = slices.index('x') > slices.index('y') wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1]) world_keep = wcs._world_keep else: world_keep = list(range(wcs.world_n_dim)) for i in range(len(coord_meta['type'])): coord_meta['visible'].append(i in world_keep) transform = WCSPixel2WorldTransform(wcs, invert_xy=invert_xy) m = wcs.axis_correlation_matrix.copy() if invert_xy: m = m[:, ::-1] if frame_class is RectangularFrame: for i, spine_name in enumerate('bltr'): pos = np.nonzero(m[:, i % 2])[0] if len(pos) > 0: index = world_keep[pos[0]] coord_meta['default_axislabel_position'][index] = spine_name coord_meta['default_ticklabel_position'][index] = spine_name coord_meta['default_ticks_position'][index] = spine_name m[pos[0], :] = 0 # In the special and common case where the frame is rectangular and # we are dealing with 2-d WCS (after slicing), we show all ticks on # all axes for backward-compatibility. if len(world_keep) == 2: for index in world_keep: coord_meta['default_ticks_position'][index] = 'bltr' elif frame_class is RectangularFrame1D: for i, spine_name in enumerate('bt'): pos = np.nonzero(m[:, 0])[0] if len(pos) > 0: index = world_keep[pos[0]] coord_meta['default_axislabel_position'][index] = spine_name coord_meta['default_ticklabel_position'][index] = spine_name coord_meta['default_ticks_position'][index] = spine_name m[pos[0], :] = 0 # In the special and common case where the frame is rectangular and # we are dealing with 2-d WCS (after slicing), we show all ticks on # all axes for backward-compatibility. if len(world_keep) == 1: for index in world_keep: coord_meta['default_ticks_position'][index] = 'bt' elif frame_class is EllipticalFrame: if 'longitude' in coord_meta['type']: lon_idx = coord_meta['type'].index('longitude') coord_meta['default_axislabel_position'][lon_idx] = 'h' coord_meta['default_ticklabel_position'][lon_idx] = 'h' coord_meta['default_ticks_position'][lon_idx] = 'h' if 'latitude' in coord_meta['type']: lat_idx = coord_meta['type'].index('latitude') coord_meta['default_axislabel_position'][lat_idx] = 'c' coord_meta['default_ticklabel_position'][lat_idx] = 'c' coord_meta['default_ticks_position'][lat_idx] = 'c' else: for i in range(len(coord_meta['type'])): if i in world_keep: index = world_keep[i] coord_meta['default_axislabel_position'][ index] = frame_class.spine_names coord_meta['default_ticklabel_position'][ index] = frame_class.spine_names coord_meta['default_ticks_position'][ index] = frame_class.spine_names return transform, coord_meta
def test_nddata_init_with_low_level_wcs(): wcs = WCS() low_level = SlicedLowLevelWCS(wcs, 5) ndd = NDData(np.ones((5, 5)), wcs=low_level) assert isinstance(ndd.wcs, BaseHighLevelWCS)
def transform_coord_meta_from_wcs(wcs, frame_class, aslice=None): is_fits_wcs = isinstance(wcs, WCS) coord_meta = {} coord_meta['name'] = [] coord_meta['type'] = [] coord_meta['wrap'] = [] coord_meta['unit'] = [] coord_meta['format_unit'] = [] invert_xy = False if aslice is not None: wcs_slice = list(aslice) wcs_slice[wcs_slice.index("x")] = slice(None) wcs_slice[wcs_slice.index("y")] = slice(None) wcs = SlicedLowLevelWCS(wcs, wcs_slice[::-1]) invert_xy = aslice.index('x') > aslice.index('y') transform = WCSPixel2WorldTransform(wcs, invert_xy=invert_xy) for idx in range(wcs.world_n_dim): axis_type = wcs.world_axis_physical_types[idx] axis_unit = u.Unit(wcs.world_axis_units[idx]) coord_wrap = None format_unit = axis_unit coord_type = 'scalar' if axis_type is not None: axis_type_split = axis_type.split('.') if "pos.helioprojective.lon" in axis_type: coord_wrap = 180. format_unit = u.arcsec coord_type = "longitude" elif "pos.helioprojective.lat" in axis_type: format_unit = u.arcsec coord_type = "latitude" elif "pos" in axis_type_split: if "lon" in axis_type_split: coord_type = "longitude" elif "lat" in axis_type_split: coord_type = "latitude" elif "ra" in axis_type_split: coord_type = "longitude" format_unit = u.hourangle elif "dec" in axis_type_split: coord_type = "latitude" elif "alt" in axis_type_split: coord_type = "longitude" elif "az" in axis_type_split: coord_type = "latitude" elif "long" in axis_type_split: coord_type = "longitude" coord_meta['type'].append(coord_type) coord_meta['wrap'].append(coord_wrap) coord_meta['format_unit'].append(format_unit) coord_meta['unit'].append(axis_unit) # For FITS-WCS, for backward-compatibility, we need to make sure that we # provide aliases based on CTYPE for the name. if is_fits_wcs: if isinstance(wcs, WCS): alias = wcs.wcs.ctype[idx][:4].replace('-', '').lower() elif isinstance(wcs, SlicedLowLevelWCS): alias = wcs._wcs.wcs.ctype[wcs._world_keep[idx]][:4].replace('-', '').lower() name = (axis_type, alias) if axis_type else alias else: name = axis_type or '' coord_meta['name'].append(name) coord_meta['default_axislabel_position'] = [''] * wcs.world_n_dim coord_meta['default_ticklabel_position'] = [''] * wcs.world_n_dim coord_meta['default_ticks_position'] = [''] * wcs.world_n_dim m = wcs.axis_correlation_matrix.copy() if invert_xy: m = m[:, ::-1] if frame_class is RectangularFrame: for i, spine_name in enumerate('bltr'): pos = np.nonzero(m[:, i % 2])[0] if len(pos) > 0: coord_meta['default_axislabel_position'][pos[0]] = spine_name coord_meta['default_ticklabel_position'][pos[0]] = spine_name coord_meta['default_ticks_position'][pos[0]] = spine_name m[pos[0], :] = 0 # In the special and common case where the frame is rectangular and # we are dealing with 2-d WCS, we show all ticks on all axes for # backward-compatibility. if len(coord_meta['type']) == 2: coord_meta['default_ticks_position'] = ['bltr'] * wcs.world_n_dim elif frame_class is EllipticalFrame: if 'longitude' in coord_meta['type']: lon_idx = coord_meta['type'].index('longitude') coord_meta['default_axislabel_position'][lon_idx] = 'h' coord_meta['default_ticklabel_position'][lon_idx] = 'h' coord_meta['default_ticks_position'][lon_idx] = 'h' if 'latitude' in coord_meta['type']: lat_idx = coord_meta['type'].index('latitude') coord_meta['default_axislabel_position'][lat_idx] = 'c' coord_meta['default_ticklabel_position'][lat_idx] = 'c' coord_meta['default_ticks_position'][lat_idx] = 'c' else: for i in range(wcs.world_n_dim): coord_meta['default_axislabel_position'][i] = frame_class.spine_names coord_meta['default_ticklabel_position'][i] = frame_class.spine_names coord_meta['default_ticks_position'][i] = frame_class.spine_names return transform, coord_meta
def _spectral_slice(self): """Slice of the WCS containing only the spectral axis""" wcs_slice = [0] * self.wcs.pixel_n_dim wcs_slice[0] = slice(0, self.n_spectral) wcs_slice = SlicedLowLevelWCS(self.wcs.low_level_wcs, wcs_slice) return wcs_slice