matplotlib / matplotlib/basemap

Bug in contour x/y values filtering in mpl_toolkits/basemap/__init__.py ?

Open
#265 12 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
817
Forks
395
PR merge metrics
No merged PRs in 30d

Description

I have been trying to plot unstructured data with **contour** and **contourf**, using the **tri=True** parameter. It works fine with contourf, but **I get a huge traceback when using contour** on the same data.

```
[...]
File "/home/share/unix_files/cdat/versions/cdat_install_uv-2.1.0_x86_64_gcc4_13/lib/python2.7/site-packages/matplotlib-1.4.0-py2.7-linux-x86_64.egg/matplotlib/tri/triangulation.py", line 55, in __init__
self.triangles, self._neighbors = _qhull.delaunay(x, y)
ValueError: x and y arrays must have a length of at least 3
```

After spending some time in the python debugger, I have found out that indeed the x and y coordinate arrays passed to the triangulation function had a zero size (and therefore less than 3 elements) because they were empty! More digging helped me find a very suspicious way of filtering the x and y values in the contour(self,x,y,data,_args,_*kwargs) function

```
# for unstructured grids, toss out points outside
# projection limb (don't use those points in triangulation).
[...]
mask = np.logical_or(xself.xmax,y>self.xmax)
x = np.compress(mask,x)
y = np.compress(mask,y)
```

Why would y be compared to the values of xmin and xmax instead of ymin and ymax, and is the logical combination ok???

I think we want to keep the values where: **xmin<=x<=xmax AND ymin<=y<=ymax**. And the **mask has to be True where we want to keep the value, in np.compress**! This is a bit misleading because it works in the opposite way that masks work in np.ma ...

The contour function works fine if I replace the mask definition above with

```
mask = np.logical_and(np.logical_and(x>=self.xmin, x<=self.xmax),
np.logical_and(y>=self.ymin, y<=self.ymax))
```

Can somebody review this? And it may be wise to use a slightly less misleading name for the _mask_ variable. Maybe replace _mask_ with _select_xy_ok_?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in mpl_toolkits/basemap/__init__.py at the contour(self, x, y, data, ...) filtering logic, then compare its inputs with the matplotlib.tri triangulation traceback. Review the proposed coordinate-bound filtering and run the existing contour or contourf tests if available. Done means contour handles the reported unstructured data without passing empty coordinate arrays to triangulation.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
data-visualization
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.