# Buggy code
def plot(
    self,
    axes=None,
    resample=None,
    annotate=True,
    interval=200,
    plot_function=None,
    **kwargs,
):
    """
    A animation plotting routine that animates each element in the
    MapCube

    Parameters
    ----------
    axes: mpl axes
        axes to plot the animation on, if none uses current axes

    resample: list or False
        Draws the map at a lower resolution to increase the speed of
        animation. Specify a list as a fraction i.e. [0.25, 0.25] to
        plot at 1/4 resolution.
        [Note: this will only work where the map arrays are the same size]

    annotate: bool
        Annotate the figure with scale and titles

    interval: int
        Animation interval in ms

    plot_function : function
        A function to be called as each map is plotted. Any variables
        returned from the function will have their ``remove()`` method called
        at the start of the next frame so that they are removed from the plot.

    Examples
    --------
    >>> import matplotlib.pyplot as plt
    >>> import matplotlib.animation as animation
    >>> from sunpy.map import Map

    >>> cube = Map(files, cube=True)   # doctest: +SKIP
    >>> ani = cube.plot(colorbar=True)   # doctest: +SKIP
    >>> plt.show()   # doctest: +SKIP

    Plot the map at 1/2 original resolution

    >>> cube = Map(files, cube=True)   # doctest: +SKIP
    >>> ani = cube.plot(resample=[0.5, 0.5], colorbar=True)   # doctest: +SKIP
    >>> plt.show()   # doctest: +SKIP

    Save an animation of the MapCube

    >>> cube = Map(res, cube=True)   # doctest: +SKIP

    >>> ani = cube.plot()   # doctest: +SKIP

    >>> Writer = animation.writers['ffmpeg']   # doctest: +SKIP
    >>> writer = Writer(fps=10, metadata=dict(artist='SunPy'), bitrate=1800)   # doctest: +SKIP

    >>> ani.save('mapcube_animation.mp4', writer=writer)   # doctest: +SKIP

    Save an animation with the limb at each time step

    >>> def myplot(fig, ax, sunpy_map):
    ...    p = sunpy_map.draw_limb()
    ...    return p
    >>> cube = Map(files, cube=True)   # doctest: +SKIP
    >>> ani = cube.peek(plot_function=myplot)   # doctest: +SKIP
    >>> plt.show()   # doctest: +SKIP

    """
    if not axes:
        axes = wcsaxes_compat.gca_wcs(self.maps[0].wcs)
    fig = axes.get_figure()

    if not plot_function:
        plot_function = lambda fig, ax, smap: []
    removes = []

    # Normal plot
    def annotate_frame(i):
        axes.set_title("{s.name}".format(s=self[i]))
        axes.set_xlabel(
            axis_labels_from_ctype(
                self[i].coordinate_system[0], self[i].spatial_units[0]
            )
        )
        axes.set_ylabel(
            axis_labels_from_ctype(
                self[i].coordinate_system[1], self[i].spatial_units[1]
            )
        )

    if resample:
        if self.all_maps_same_shape():
            resample = u.Quantity(self.maps[0].dimensions) * np.array(resample)
            ani_data = [amap.resample(resample) for amap in self.maps]
        else:
            raise ValueError("Maps in mapcube do not all have the same shape.")
    else:
        ani_data = self.maps

    im = ani_data[0].plot(axes=axes, **kwargs)

    def updatefig(i, im, annotate, ani_data, removes):
        while removes:
            removes.pop(0).remove()

        im.set_array(ani_data[i].data)
        im.set_cmap(ani_data[i].plot_settings["cmap"])

        norm = deepcopy(ani_data[i].plot_settings["norm"])
        # The following explicit call is for bugged versions of Astropy's
        # ImageNormalize
        norm.autoscale_None(ani_data[i].data)
        im.set_norm(norm)

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

        if annotate:
            annotate_frame(i)
        removes += list(plot_function(fig, axes, ani_data[i]))

    ani = matplotlib.animation.FuncAnimation(
        fig,
        updatefig,
        frames=list(range(0, len(ani_data))),
        fargs=[im, annotate, ani_data, removes],
        interval=interval,
        blit=False,
    )

    return ani


# Traceback (TypeError)
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'

# Fixed code
def plot(
    self,
    axes=None,
    resample=None,
    annotate=True,
    interval=200,
    plot_function=None,
    **kwargs,
):
    """
    A animation plotting routine that animates each element in the
    MapCube

    Parameters
    ----------
    axes: mpl axes
        axes to plot the animation on, if none uses current axes

    resample: list or False
        Draws the map at a lower resolution to increase the speed of
        animation. Specify a list as a fraction i.e. [0.25, 0.25] to
        plot at 1/4 resolution.
        [Note: this will only work where the map arrays are the same size]

    annotate: bool
        Annotate the figure with scale and titles

    interval: int
        Animation interval in ms

    plot_function : function
        A function to be called as each map is plotted. Any variables
        returned from the function will have their ``remove()`` method called
        at the start of the next frame so that they are removed from the plot.

    Examples
    --------
    >>> import matplotlib.pyplot as plt
    >>> import matplotlib.animation as animation
    >>> from sunpy.map import Map

    >>> cube = Map(files, cube=True)   # doctest: +SKIP
    >>> ani = cube.plot(colorbar=True)   # doctest: +SKIP
    >>> plt.show()   # doctest: +SKIP

    Plot the map at 1/2 original resolution

    >>> cube = Map(files, cube=True)   # doctest: +SKIP
    >>> ani = cube.plot(resample=[0.5, 0.5], colorbar=True)   # doctest: +SKIP
    >>> plt.show()   # doctest: +SKIP

    Save an animation of the MapCube

    >>> cube = Map(res, cube=True)   # doctest: +SKIP

    >>> ani = cube.plot()   # doctest: +SKIP

    >>> Writer = animation.writers['ffmpeg']   # doctest: +SKIP
    >>> writer = Writer(fps=10, metadata=dict(artist='SunPy'), bitrate=1800)   # doctest: +SKIP

    >>> ani.save('mapcube_animation.mp4', writer=writer)   # doctest: +SKIP

    Save an animation with the limb at each time step

    >>> def myplot(fig, ax, sunpy_map):
    ...    p = sunpy_map.draw_limb()
    ...    return p
    >>> cube = Map(files, cube=True)   # doctest: +SKIP
    >>> ani = cube.peek(plot_function=myplot)   # doctest: +SKIP
    >>> plt.show()   # doctest: +SKIP

    """
    if not axes:
        axes = wcsaxes_compat.gca_wcs(self.maps[0].wcs)
    fig = axes.get_figure()

    if not plot_function:
        plot_function = lambda fig, ax, smap: []
    removes = []

    # Normal plot
    def annotate_frame(i):
        axes.set_title("{s.name}".format(s=self[i]))
        axes.set_xlabel(
            axis_labels_from_ctype(
                self[i].coordinate_system[0], self[i].spatial_units[0]
            )
        )
        axes.set_ylabel(
            axis_labels_from_ctype(
                self[i].coordinate_system[1], self[i].spatial_units[1]
            )
        )

    if resample:
        if self.all_maps_same_shape():
            resample = u.Quantity(self.maps[0].dimensions) * np.array(resample)
            ani_data = [amap.resample(resample) for amap in self.maps]
        else:
            raise ValueError("Maps in mapcube do not all have the same shape.")
    else:
        ani_data = self.maps

    im = ani_data[0].plot(axes=axes, **kwargs)

    def updatefig(i, im, annotate, ani_data, removes):
        while removes:
            removes.pop(0).remove()

        im.set_array(ani_data[i].data)
        im.set_cmap(ani_data[i].plot_settings["cmap"])

        norm = deepcopy(ani_data[i].plot_settings["norm"])
        # The following explicit call is for bugged versions of Astropy's
        # ImageNormalize
        norm.autoscale_None(ani_data[i].data)
        im.set_norm(norm)

        if wcsaxes_compat.is_wcsaxes(axes):
            im.axes.reset_wcs(ani_data[i].wcs)
            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))
            )

        if annotate:
            annotate_frame(i)
        removes += list(plot_function(fig, axes, ani_data[i]))

    ani = matplotlib.animation.FuncAnimation(
        fig,
        updatefig,
        frames=list(range(0, len(ani_data))),
        fargs=[im, annotate, ani_data, removes],
        interval=interval,
        blit=False,
    )

    return ani