Skip to content
This repository has been archived by the owner on Jun 16, 2018. It is now read-only.

Commit

Permalink
Merge a308597 into fb7e8d2
Browse files Browse the repository at this point in the history
  • Loading branch information
lpsinger committed Oct 1, 2016
2 parents fb7e8d2 + a308597 commit f335043
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 2 deletions.
32 changes: 32 additions & 0 deletions docs/custom_frames.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,38 @@ following example shows how to use the built-in
# Clip the image to the frame
im.set_clip_path(ax.coords.frame.patch)

The :class:`~wcsaxes.frame.EllipticalFrame` class is especially useful for
all-sky plots such as Aitoff projections:

.. plot::
:context: reset
:include-source:
:align: center

from astropy.wcs import WCS
from wcsaxes import datasets
from wcsaxes.frame import EllipticalFrame
from matplotlib import patheffects

hdu = datasets.fetch_rosat_hdu()
wcs = WCS(hdu.header)

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(7, 4))
ax = fig.add_axes([0.05, 0.05, 0.9, 0.9], projection=wcs,
frame_class=EllipticalFrame)

path_effects=[patheffects.withStroke(linewidth=3, foreground='black')]
ax.coords.grid(color='white')
ax.coords['glon'].set_ticklabel(color='white', path_effects=path_effects)

im = ax.imshow(hdu.data, vmin=0., vmax=300.,
cmap=plt.cm.inferno, origin='lower')

# Clip the image to the frame
im.set_clip_path(ax.coords.frame.patch)

However, you can also write your own frame class. The idea is to set up any
number of connecting spines that define the frame. You can define a frame as a
spine, but if you define it as multiple spines you will be able to control on
Expand Down
5 changes: 5 additions & 0 deletions docs/ticks_labels_grid.rst
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ We can set the defaults back using:
lat.set_ticklabel_position('l')
lat.set_axislabel_position('l')

On plots with elliptical frames, three alternate tick positions are supported:
``c`` for the outer circular or elliptical border, ``h`` for the horizontal
axis (which is usually the major axis of the ellipse), and ``v`` for the
vertical axis (which is usually the minor axis of the ellipse).


Hiding ticks and tick labels
============================
Expand Down
18 changes: 17 additions & 1 deletion wcsaxes/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
CoordinateTransform)
from .coordinates_map import CoordinatesMap
from .utils import get_coord_meta
from .frame import RectangularFrame
from .frame import EllipticalFrame, RectangularFrame
import numpy as np

__all__ = ['WCSAxes', 'WCSAxesSubplot']
Expand Down Expand Up @@ -185,6 +185,22 @@ def reset_wcs(self, wcs=None, slices=None, transform=None, coord_meta=None):
self.coords[coord_index].set_axislabel_position('')
self.coords[coord_index].set_ticklabel_position('')
self.coords[coord_index].set_ticks_position('')
# Common default settings for Elliptical Frame
elif self.frame_class is EllipticalFrame:
for coord_index in range(len(self.slices)):
if self.slices[coord_index] == 'x':
self.coords[coord_index].set_axislabel_position('h')
self.coords[coord_index].set_ticklabel_position('h')
self.coords[coord_index].set_ticks_position('h')
elif self.slices[coord_index] == 'y':
self.coords[coord_index].set_ticks_position('c')
self.coords[coord_index].set_axislabel_position('c')
self.coords[coord_index].set_ticklabel_position('c')
else:
self.coords[coord_index].set_axislabel_position('')
self.coords[coord_index].set_ticklabel_position('')
self.coords[coord_index].set_ticks_position('')


def draw(self, renderer, inframe=False):

Expand Down
29 changes: 28 additions & 1 deletion wcsaxes/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def update_spines(self):

class EllipticalFrame(BaseFrame):

spine_names = 'c'
spine_names = 'chv'

def update_spines(self):

Expand All @@ -218,3 +218,30 @@ def update_spines(self):
theta = np.linspace(0., 2 * np.pi, 1000)
self['c'].data = np.array([xmid + dx * np.cos(theta),
ymid + dy * np.sin(theta)]).transpose()
self['h'].data = np.array([np.linspace(xmin, xmax, 1000),
np.repeat(ymid, 1000)]).transpose()
self['v'].data = np.array([np.repeat(xmid, 1000),
np.linspace(ymin, ymax, 1000)]).transpose()

def _update_patch_path(self):
"""Override path patch to include only the outer ellipse,
not the major and minor axes in the middle."""

self.update_spines()
vertices = self['c'].data

if self._path is None:
self._path = Path(vertices)
else:
self._path.vertices = vertices

def draw(self, renderer):
"""Override to draw only the outer ellipse,
not the major and minor axes in the middle.
FIXME: we may want to add a general method to give the user control
over which spines are drawn."""
axis = 'c'
x, y = self[axis].pixel[:, 0], self[axis].pixel[:, 1]
line = Line2D(x, y, linewidth=self._linewidth, color=self._color, zorder=1000)
line.draw(renderer)

0 comments on commit f335043

Please sign in to comment.