Repository: SciTools/cartopy

Issue:
SlippyImageArtist cannot be composited
For example, take the WMTS example and add a second layer. Then attempt to save as a PDF.

``` python
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

url = 'http://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi'
layer1 = 'VIIRS_CityLights_2012'
layer2 = 'ASTER_GDEM_Color_Index'

ax = plt.axes(projection=ccrs.PlateCarree())
ax.add_wmts(url, layer1)
ax.add_wmts(url, layer2)
ax.set_extent((-15, 25, 35, 60))

plt.title('Suomi NPP Earth at night April/October 2012')
plt.savefig('test.pdf')
plt.show()
```

which results in:

``` python
Traceback (most recent call last):
  File "wmts.py", line 33, in main
    plt.savefig('test.pdf')
  File "/usr/lib64/python2.7/site-packages/matplotlib/pyplot.py", line 577, in savefig
    res = fig.savefig(*args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/matplotlib/figure.py", line 1476, in savefig
    self.canvas.print_figure(*args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_qt5agg.py", line 161, in print_figure
    FigureCanvasAgg.print_figure(self, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/matplotlib/backend_bases.py", line 2211, in print_figure
    **kwargs)
  File "/usr/lib64/python2.7/site-packages/matplotlib/backends/backend_pdf.py", line 2485, in print_pdf
    self.figure.draw(renderer)
  File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/matplotlib/figure.py", line 1085, in draw
    func(*args)
  File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/cartopy/mpl/geoaxes.py", line 359, in draw
    inframe=inframe)
  File "/usr/lib64/python2.7/site-packages/matplotlib/artist.py", line 59, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/matplotlib/axes/_base.py", line 2081, in draw
    for z, im in zorder_images]
  File "/usr/lib64/python2.7/site-packages/matplotlib/image.py", line 580, in make_image
    raise RuntimeError('You must first set the image'
RuntimeError: You must first set the image array or the image attribute
```

I think maybe `SlippyImageArtist` should be overriding `make_image`, too.



Discussion:
:+1: - looks like the right solution.

I was just looking into implementing this, but it's a bit more difficult than I had hoped. Matplotlib expects `make_image` to return a single image for composition. An idea I had was to simply combine the images here, but that invokes all the perils of compositing all over again (i.e., getting the location right, the pixel density may not be the same, etc.), unless there are some assumptions that can be made here?

I think matplotlib 2.x will query a `can_composite` setting which will allow turning it off per-image at least.

> unless there are some assumptions that can be made here?

Hmmm. I see. Perhaps we need to cease calling the SlippyImageArtist an image, and put it in the `axes.artists` list... they will not be treated as images at that point, and will simply call their associated `draw` method as expected.


Resolving patch:
diff --git a/lib/cartopy/mpl/slippy_image_artist.py b/lib/cartopy/mpl/slippy_image_artist.py
--- a/lib/cartopy/mpl/slippy_image_artist.py
+++ b/lib/cartopy/mpl/slippy_image_artist.py
@@ -74,3 +74,8 @@ def draw(self, renderer, *args, **kwargs):
             with ax.hold_limits():
                 self.set_extent(extent)
             super(SlippyImageArtist, self).draw(renderer, *args, **kwargs)
+
+    def can_composite(self):
+        # As per https://github.com/SciTools/cartopy/issues/689, disable
+        # compositing multiple raster sources.
+        return False


Test patch: