Repository: SciTools/cartopy

Issue:
SystemError: error return without exception set
```
import iris
import cartopy
import matplotlib.pyplot as plt
import iris.quickplot as qplt
import cartopy.crs as ccrs


cube = iris.load_cube(iris.sample_data_path('air_temp.pp'))

plt.axes(projection=ccrs.NorthPolarStereo())

qplt.contourf(cube)

plt.gca().gridlines()

#plt.gca().set_global()

plt.show()
```

The code above produces the following when run;

```
ValueError: zero-size array to fmin.reduce without identity
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/local/sci/lib/python2.7/lib-tk/Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "/usr/local/sci/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 276, in resize
    self.show()
  File "/usr/local/sci/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 348, in draw
    FigureCanvasAgg.draw(self)
  File "/usr/local/sci/lib/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 439, in draw
    self.figure.draw(self.renderer)
  File "/usr/local/sci/lib/python2.7/site-packages/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/usr/local/sci/lib/python2.7/site-packages/matplotlib/figure.py", line 999, in draw
    func(*args)
  File "/usr/local/sci/lib/python2.7/site-packages/matplotlib/artist.py", line 54, in draw_wrapper
    draw(artist, renderer, *args, **kwargs)
  File "/net/home/h04/mwalker/Git/cartopy/lib/cartopy/mpl/geoaxes.py", line 279, in draw
    gl._draw_gridliner(background_patch=self.background_patch)
  File "/net/home/h04/mwalker/Git/cartopy/lib/cartopy/mpl/gridliner.py", line 280, in _draw_gridliner
    background_patch=background_patch)
  File "/net/home/h04/mwalker/Git/cartopy/lib/cartopy/mpl/gridliner.py", line 428, in _axes_domain
    x_range = np.nanmin(inside[:, 0]), np.nanmax(inside[:, 0])
  File "/usr/local/sci/lib/python2.7/site-packages/numpy/lib/function_base.py", line 1507, in nanmin
    return np.fmin.reduce(a.flat)
SystemError: error return without exception set
```

If however, this code is run with the set_global line uncommented, then the code will execute correctly. Further, if the code is run with the gridlines() line commented out, then the code will also run, but the plot will be a tiny plot, as descibed in #321. 

It therefore seems that the issue may be due to an inability to add grid lines to an object that is as small as what is being debt with here (less than 1 pixel).

If this is the root of the problem, then a solution to #321 would prevent this error from arising, but it may still be worth catching. 



Discussion:
This appears to remain an unfixed issue.  I'm afraid with Cartopy v0.11.0 release taking place, I think we should modify the milestone for this issue to 0.12.0, @pelson?

This should now be an easy fix. The exception now looks something like:

```
  File "lib/cartopy/mpl/gridliner.py", line 427, in _axes_domain
    x_range = np.nanmin(inside[:, 0]), np.nanmax(inside[:, 0])
  File "numpy/lib/function_base.py", line 1531, in nanmin
    return np.fmin.reduce(a.flat)
ValueError: zero-size array to reduction operation fmin which has no identity
```

Might be worth putting a fix in if you're prepared to do so @cpelley, otherwise I agree, let's hold fire on this one until 0.12.

Sure, I'll see if time permits and let you know :)


Resolving patch:
diff --git a/lib/cartopy/mpl/gridliner.py b/lib/cartopy/mpl/gridliner.py
--- a/lib/cartopy/mpl/gridliner.py
+++ b/lib/cartopy/mpl/gridliner.py
@@ -426,8 +426,15 @@ def _axes_domain(self, nx=None, ny=None, background_patch=None):
 #                         horizontalalignment='right')
 
         inside = in_data[ok, :]
-        x_range = np.nanmin(inside[:, 0]), np.nanmax(inside[:, 0])
-        y_range = np.nanmin(inside[:, 1]), np.nanmax(inside[:, 1])
+
+        # If there were no data points in the axes we just use the x and y
+        # range of the projection.
+        if inside.size == 0:
+            x_range = self.crs.x_limits
+            y_range = self.crs.y_limits
+        else:
+            x_range = np.nanmin(inside[:, 0]), np.nanmax(inside[:, 0])
+            y_range = np.nanmin(inside[:, 1]), np.nanmax(inside[:, 1])
 
         # XXX Cartopy specific thing. Perhaps make this bit a specialisation
         # in a subclass...
@@ -436,7 +443,7 @@ def _axes_domain(self, nx=None, ny=None, background_patch=None):
             x_range = np.clip(x_range, *crs.x_limits)
             y_range = np.clip(y_range, *crs.y_limits)
 
-            # if the limit is >90 of the full x limit, then just use the full
+            # if the limit is >90% of the full x limit, then just use the full
             # x limit (this makes circular handling better)
             prct = np.abs(np.diff(x_range) / np.diff(crs.x_limits))
             if prct > 0.9:


Test patch: