Repository: sunpy/sunpy

Issue:
Error when calling plot method on MapCube
Calling the plot method on a MapCube leads to an error and subsequently the animation can't be saved to a video a minimal script to reproduce error is below.

Python: 3.6
Matplotlib: 2.2.2
Astropy: 3.0.2
Sunpy: 0.9.0

```python 
from astropy import units as u

from sunpy.net import Fido, attrs as a
from sunpy.map import Map

results = Fido.search(a.Time('2013/07/06 09:30', '2013/07/06 09:31'), a.Instrument('aia'), a.Wavelength(171 * u.angstrom))
    
downloaded_files = Fido.fetch(results)

map_cube = Map(downloaded_files, cube=True)

ani = map_cube.plot()
# Crash here, stack trace below
#ani = map_cube.peek().get_animation() # This works but have progress bars cover axis
ani.save('test.mp4')
```

```python
TypeError                                 Traceback (most recent call last)
<ipython-input-18-ab15991fbba2> in <module>()
     12 ani = map_cube.plot()
     13 #ani = map_cube.peek().get_animation() # This works but have progress bars cover axis
---> 14 ani.save('test.mp4')

~/.virtualenvs/gen/lib/python3.6/site-packages/matplotlib/animation.py in save(self, filename, writer, fps, dpi, codec, bitrate, extra_args, metadata, extra_anim, savefig_kwargs)
   1193                 for anim in all_anim:
   1194                     # Clear the initial frame
-> 1195                     anim._init_draw()
   1196                 for data in zip(*[a.new_saved_frame_seq() for a in all_anim]):
   1197                     for anim, d in zip(all_anim, data):

~/.virtualenvs/gen/lib/python3.6/site-packages/matplotlib/animation.py in _init_draw(self)
   1748         # artists.
   1749         if self._init_func is None:
-> 1750             self._draw_frame(next(self.new_frame_seq()))
   1751
   1752         else:

~/.virtualenvs/gen/lib/python3.6/site-packages/matplotlib/animation.py in _draw_frame(self, framedata)
   1770         # Call the func with framedata and args. If blitting is desired,
   1771         # func needs to return a sequence of any artists that were modified.
-> 1772         self._drawn_artists = self._func(framedata, *self._args)
   1773         if self._blit:
   1774             if self._drawn_artists is None:

~/.virtualenvs/gen/lib/python3.6/site-packages/sunpy/map/mapcube.py in updatefig(i, im, annotate, ani_data, removes)
    206             if wcsaxes_compat.is_wcsaxes(axes):
    207                 im.axes.reset_wcs(ani_data[i].wcs)
--> 208                 wcsaxes_compat.default_wcs_grid(axes)
    209             else:
    210                 im.set_extent(np.concatenate((ani_data[i].xrange.value,

TypeError: default_wcs_grid() missing 2 required positional arguments: 'units' and 'ctypes'
```


Discussion:
@samaloney I am surprised that there *is* a save method `MapCubeAnimator`. I think the misbehaviour of `get_animation` is the more pressing issue here as that's the way I would expect you to have to do this.
@Cadair The docs might need to be update too then as I was just following the examples at the bottom here at http://docs.sunpy.org/en/v0.9.0/api/sunpy.map.MapCube.html
No wait I am getting confused.

This is a nasty bug, can I have the output of `sunpy.system_info()` please?
oh actually don't worry I see the bug. It looks like the call signature of `wcsaxes_compat.default_wcs_grid` has changed and the `updatefig` callback wasn't updated. Should be easy enough to add the extra arguments from the map.
Yea so `update` needs to be modified to pass `units` and `ctypes` as well as the axes?
yeah which should be extractable from the map, which is `ani_data[i]` inside that function iirc. You can have a look at `GenericMap.plot` for how to construct those arguments from the map data.

Resolving patch:
diff --git a/sunpy/map/mapcube.py b/sunpy/map/mapcube.py
--- a/sunpy/map/mapcube.py
+++ b/sunpy/map/mapcube.py
@@ -203,7 +203,8 @@ def updatefig(i, im, annotate, ani_data, removes):
 
             if wcsaxes_compat.is_wcsaxes(axes):
                 im.axes.reset_wcs(ani_data[i].wcs)
-                wcsaxes_compat.default_wcs_grid(axes)
+                wcsaxes_compat.default_wcs_grid(axes, ani_data[i].spatial_units,
+                                                ani_data[i].coordinate_system)
             else:
                 im.set_extent(np.concatenate((ani_data[i].xrange.value,
                                               ani_data[i].yrange.value)))


Test patch:
diff --git a/sunpy/map/tests/test_mapcube.py b/sunpy/map/tests/test_mapcube.py
--- a/sunpy/map/tests/test_mapcube.py
+++ b/sunpy/map/tests/test_mapcube.py
@@ -147,3 +147,12 @@ def test_all_meta(mapcube_all_the_same):
     assert len(meta) == 2
     assert np.all(np.asarray([isinstance(h, MetaDict) for h in meta]))
     assert np.all(np.asarray([meta[i] == mapcube_all_the_same[i].meta for i in range(0, len(meta))]))
+
+def test_plot(mapcube_all_the_same, tmpdir):
+    # Regression test for #2626 - trying to save animation after calling plot 
+    # on MapCube caused error
+    file = tmpdir.join("movie.gif")
+    ani = mapcube_all_the_same.plot()
+    # The error was is actually caused when the updatefig method is called this is a hack
+    # to cause the error with out actually having to save an animation.
+    ani._step()