Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal bug when transforming zero-length arrays #1115

Closed
meridionaljet opened this issue Sep 12, 2018 · 3 comments
Closed

Fatal bug when transforming zero-length arrays #1115

meridionaljet opened this issue Sep 12, 2018 · 3 comments

Comments

@meridionaljet
Copy link

meridionaljet commented Sep 12, 2018

In Cartopy v0.16.0, GeoAxes.transform_non_affine() fails when the coordinate array is zero-length. The code as it is now is as follows:

def transform_non_affine(self, xy):
    prj = self.target_projection
    if isinstance(xy, np.ndarray):
        return prj.transform_points(self.source_projection,
                                    xy[:, 0], xy[:, 1])[:, 0:2]
    else:
        x, y = xy
        x, y = prj.transform_point(x, y, self.source_projection)
        return x, y

If xy.shape == (0,2), prj.transform_points() fails. This was occurring for me when calling GeoAxes.barbs() with arrays of all NaNs, during which matplotlib was calling the transform on empty arrays. This happens in v0.15.1 as well.

A minimal working example (tested in environment Python=3.6, cartopy=0.16.0, matplotlib=2.0.2):

import cartopy
from matplotlib import pyplot as plt
import numpy as np

fig, ax = plt.subplots(subplot_kw={'projection': cartopy.crs.PlateCarree()})
# Make all-missing data
u = np.nan*np.zeros(10)
v = u.copy()
x = np.arange(10)
y = x.copy()
# Plot
ax.barbs(x, y, u, v)

>>> python cartopy_example.py 
Traceback (most recent call last):
  File "cartopy_example.py", line 12, in <module>
    ax.barbs(x, y, u, v)
  File "/home/user/anaconda3/lib/python3.6/site-packages/cartopy/mpl/geoaxes.py", line 1826, in barbs
    return matplotlib.axes.Axes.barbs(self, x, y, u, v, *args, **kwargs)
  File "/home/user/anaconda3/lib/python3.6/site-packages/matplotlib/__init__.py", line 1898, in inner
    return func(ax, *args, **kwargs)
  File "/home/user/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 4644, in barbs
    self.add_collection(b, autolim=True)
  File "/home/user/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 1762, in add_collection
    self.update_datalim(collection.get_datalim(self.transData))
  File "/home/user/anaconda3/lib/python3.6/site-packages/matplotlib/collections.py", line 217, in get_datalim
    offsets = transOffset.transform_non_affine(offsets)
  File "/home/user/anaconda3/lib/python3.6/site-packages/matplotlib/transforms.py", line 2376, in transform_non_affine
    return self._a.transform_non_affine(points)
  File "/home/user/anaconda3/lib/python3.6/site-packages/cartopy/mpl/geoaxes.py", line 137, in transform_non_affine
    xy[:, 0], xy[:, 1])[:, 0:2]
  File "lib/cartopy/_crs.pyx", line 381, in cartopy._crs.CRS.transform_points
IndexError: Out of bounds on buffer access (axis 0)

Since the transform should return a (n, 2) array, the following easy fix could be implemented by checking for the zero-length array case:

def transform_non_affine(self, xy):
    prj = self.target_projection
    if isinstance(xy, np.ndarray):
        if xy.size == 0:
            return np.zeros((0, 2))
        return prj.transform_points(self.source_projection,
                                    xy[:, 0], xy[:, 1])[:, 0:2]
    else:
        x, y = xy
        x, y = prj.transform_point(x, y, self.source_projection)
        return x, y

I don't know if you would prefer to handle this case in prj.transform_points() instead, but it's an easy fix. Unfortunately this is proving highly detrimental to plotting functions that may contain missing data at the moment, as the user should normally be able to call matplotlib's plotting functions on all-NaN arrays.

@QuLogic
Copy link
Member

QuLogic commented Sep 13, 2018

Please provide a complete example to reproduce this.

@meridionaljet
Copy link
Author

Please provide a complete example to reproduce this.

I have added an example to the original post.

@QuLogic
Copy link
Member

QuLogic commented Sep 27, 2018

Thank you for the example. This bug is a duplicate of #1060 and is fixed by #1062, which will be in the next release.

@QuLogic QuLogic closed this as completed Sep 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants