Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into docfix_06
Browse files Browse the repository at this point in the history
  • Loading branch information
ehsteve committed Jul 27, 2015
2 parents 66f8ece + 17b8f63 commit bb72e79
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 22 deletions.
74 changes: 58 additions & 16 deletions doc/source/guide/plotting.rst
Expand Up @@ -169,47 +169,89 @@ highlight a region of interest, and change the plot title.
plt.colorbar()
plt.show()

By default :ref:`map` uses the `wcsaxes <http://wcsaxes.readthedocs.org/>`_
package to improve the representation of world coordinates. In the
examples above the axes were normal matplotlib axes.
To create a custom `wcsaxes.WCSAxes` instance do the following ::

Plotting Maps with wcsaxes
--------------------------

By default :ref:map checks if the `wcsaxes <http://wcsaxes.readthedocs.org/>`_
package has been installed. If it is installed,
then `wcsaxes` is used to improve the representation of world coordinates,
and calling ~sunpy.map.GenericMap.plot or~sunpy.map.GenericMap.peek() will use
wcsaxes for plotting. Unless a standard `matplotlib.axes.Axes` object is created.

To explicitly create a `wcsaxes.WCSAxes` instance do the following ::

>>> fig = plt.figure() # doctest: +SKIP
>>> ax = plt.subplot(projection=smap.wcs) # doctest: +SKIP

when overplotting data and using wcsaxes you have to use the transform keyword
argument, also the native coordinate system of a `~wcsaxes.WCSAxes` is always
in degrees ::
when plotting on a `~wcsaxes.WCSAxes` axes, it will by default plot in pixel
coordinates, you can override this behavior and plot in 'world' coordinates
by getting the transformation from the axes with ``ax.get_transform('world')``.
Note: World coordinates are always in **degrees** so you will have to convert
to degrees.::

>>> smap.plot() # doctest: +SKIP
>>> ax.plot((100*u.arcsec).to(u.deg), (500*u.arcsec).to(u.deg),
... transform=ax.get_transform('world')) # doctest: +SKIP

Finally, here is a more complex example:
Finally, here is a more complex example using SunPy maps, wcsaxes and Astropy
units to plot a AIA image and a zoomed in view of an active region.

.. plot::
:include-source:

import matplotlib.pyplot as plt
from matplotlib import patches
import astropy.units as u

import sunpy.map
import matplotlib.pyplot as plt
import sunpy.data.sample


# Define a region of interest
l = 250*u.arcsec
x0 = -100*u.arcsec
y0 = -400*u.arcsec

# Create a SunPy Map, and a second submap over the region of interest.
smap = sunpy.map.Map(sunpy.data.sample.AIA_171_IMAGE)
submap = smap.submap([-100-250, -100+250]*u.arcsec, [-400-250, -400+250]*u.arcsec)
rect = patches.Rectangle([-100-250, -400-250], 500, 500, color = 'white', fill=False)
submap = smap.submap(u.Quantity([x0-l, x0+l]), u.Quantity([y0-l, y0+l]))

fig = plt.figure()
ax1 = fig.add_subplot(2,1,1)


# Create a new matplotlib figure, larger than default.
fig = plt.figure(figsize=(5,12))

# Add a first Axis, using the WCS from the map.
ax1 = fig.add_subplot(2,1,1, projection=smap.wcs)

# Plot the Map on the axes with default settings.
smap.plot()

# Define a region to highlight with a box
# We have to convert the region of interest to degress, and then get the raw values.
bottom_left = u.Quantity([x0-l, y0-l]).to(u.deg).value
l2 = (l*2).to(u.deg).value

# create the rectangle, we use the world transformation to plot in physical units.
rect = patches.Rectangle(bottom_left, l2, l2, color='white', fill=False,
transform=ax1.get_transform('world'))

# Add the rectangle to the plot.
ax1.add_artist(rect)

ax2 = fig.add_subplot(2,1,2)


# Create a second axis on the plot.
ax2 = fig.add_subplot(2,1,2, projection=submap.wcs)

submap.plot()

# Add a overlay grid.
submap.draw_grid(grid_spacing=10*u.deg)
ax2.set_title('submap')
fig.subplots_adjust(hspace=0.4)

# Change the title.
ax2.set_title('Zoomed View')


plt.show()
18 changes: 13 additions & 5 deletions sunpy/map/mapcube.py
Expand Up @@ -4,11 +4,11 @@

import numpy as np
import matplotlib.animation
import matplotlib.pyplot as plt

from sunpy.map import GenericMap

from sunpy.visualization.mapcubeanimator import MapCubeAnimator
from sunpy.visualization import wcsaxes_compat
from sunpy.util import expand_list

__all__ = ['MapCube']
Expand Down Expand Up @@ -161,7 +161,7 @@ def plot(self, axes=None, resample=None, annotate=True,
"""
if not axes:
axes = plt.gca()
axes = wcsaxes_compat.gca_wcs(self.maps[0].wcs)
fig = axes.get_figure()

if not plot_function:
Expand Down Expand Up @@ -200,10 +200,18 @@ def annotate_frame(i):
def updatefig(i, im, annotate, ani_data, removes):
while removes:
removes.pop(0).remove()

im.set_array(ani_data[i].data)
im.set_cmap(self.maps[i].cmap)
im.set_norm(self.maps[i].mpl_color_normalizer)
im.set_extent(np.concatenate((self.maps[i].xrange.value, self.maps[i].yrange.value)))
im.set_cmap(self.maps[i].plot_settings['cmap'])
im.set_norm(self.maps[i].plot_settings['norm'])

if wcsaxes_compat.is_wcsaxes(axes):
im.axes.reset_wcs(self.maps[i].wcs)
wcsaxes_compat.default_wcs_grid(axes)
else:
im.set_extent(np.concatenate((self.maps[i].xrange.value,
self.maps[i].yrange.value)))

if annotate:
annotate_frame(i)
removes += list(plot_function(fig, axes, self.maps[i]))
Expand Down
16 changes: 15 additions & 1 deletion sunpy/visualization/mapcubeanimator.py
Expand Up @@ -2,7 +2,8 @@

__all__ = ['MapCubeAnimator']

from sunpy.visualization import imageanimator
from sunpy.visualization import imageanimator, wcsaxes_compat
from sunpy.visualization.wcsaxes_compat import HAVE_WCSAXES, FORCE_NO_WCSAXES

class MapCubeAnimator(imageanimator.BaseFuncAnimator):
"""
Expand Down Expand Up @@ -88,6 +89,10 @@ def updatefig(self, val, im, slider):
im.set_array(self.data[i].data)
im.set_cmap(self.mapcube[i].plot_settings['cmap'])
im.set_norm(self.mapcube[i].plot_settings['norm'])
if wcsaxes_compat.is_wcsaxes(im.axes):
im.axes.reset_wcs(self.mapcube[i].wcs)
wcsaxes_compat.default_wcs_grid(im.axes)

# Having this line in means the plot will resize for non-homogenous
# maps. However it also means that if you zoom in on the plot bad
# things happen.
Expand Down Expand Up @@ -121,6 +126,15 @@ def _annotate_plot(self, ind):
self.axes.set_xlabel(xlabel)
self.axes.set_ylabel(ylabel)

def _get_main_axes(self):
"""
Create an axes which is wcsaxes if we have that...
"""
if HAVE_WCSAXES and not FORCE_NO_WCSAXES:
return self.fig.add_subplot(111, projection=self.mapcube[0].wcs)
else:
return self.fig.add_subplot(111)

def plot_start_image(self, ax):
im = self.mapcube[0].plot(annotate=self.annotate, axes=ax,
**self.imshow_kwargs)
Expand Down

0 comments on commit bb72e79

Please sign in to comment.