Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into new_labelling
Browse files Browse the repository at this point in the history
Conflicts:
	lib/cartopy/tests/mpl/test_ticker.py
  • Loading branch information
stefraynaud committed Feb 4, 2019
2 parents 47b5f29 + eff8ba5 commit ace4511
Show file tree
Hide file tree
Showing 24 changed files with 390 additions and 812 deletions.
2 changes: 1 addition & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ environment:
PACKAGES: "cython numpy matplotlib-base proj4 pykdtree scipy"
- PYTHON_VERSION: "2.7"
CONDA_INSTALL_LOCN: "C:\\Miniconda-x64"
PACKAGES: "cython=0.17 numpy=1.10.0 matplotlib=1.5.1 nose proj4=4.9.1 scipy=0.16.0 mock msinttypes futures"
PACKAGES: "cython=0.28 numpy=1.10.0 matplotlib=1.5.1 nose proj4=4.9.1 scipy=0.16.0 mock msinttypes futures"

install:
# Install miniconda
Expand Down
19 changes: 19 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# .coveragerc to control coverage.py
#

[run]
branch = True
omit =
lib/cartopy/examples/*
lib/cartopy/sphinxext/*
lib/cartopy/tests/*
lib/cartopy/_version.py
*.pxd
plugins = Cython.Coverage

[report]
exclude_lines =
pragma: no cover
def __repr__
if __name__ == .__main__.:
File renamed without changes.
16 changes: 13 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ env:
# These ancient versions are linked to an old libgfortran, but that version
# isn't pinned in the package metadata
- PYTHON_VERSION=2.7
PACKAGES="cython=0.17 numpy=1.10.0 matplotlib=1.5.1 nose proj4=4.9.1 scipy=0.16.0 libgfortran=1 mock futures"
PACKAGES="cython=0.28 numpy=1.10.0 matplotlib=1.5.1 nose proj4=4.9.1 scipy=0.16.0 libgfortran=1 mock futures"
- PYTHON_VERSION=3.5
PACKAGES="cython=0.23.1 numpy=1.10.0 matplotlib=1.5.1 nose proj4=4.9.1 scipy=0.16.0 libgfortran=1"
PACKAGES="cython=0.28 numpy=1.10.0 matplotlib=1.5.1 nose proj4=4.9.1 scipy=0.16.0 libgfortran=1"
PYTHONHASHSEED=0 # So pytest-xdist works.
- NAME="Latest everything."
PYTHON_VERSION=3.6
Expand Down Expand Up @@ -47,6 +47,10 @@ install:
# Customise the testing environment
# ---------------------------------
- PACKAGES="$PACKAGES pillow pytest pytest-xdist filelock pep8 pyshp shapely six requests pyepsg owslib"
- if [[ "$NAME" == "Latest everything"* ]]; then
PACKAGES="$PACKAGES pytest-cov coveralls";
export CYTHON_COVERAGE=1;
fi
- conda install --quiet $PACKAGES

# Conda debug
Expand All @@ -69,11 +73,17 @@ script:
- python $TRAVIS_BUILD_DIR/tools/feature_download.py gshhs physical --dry-run

- if [[ "$NAME" == "Latest everything"* ]]; then
CARTOPY_GIT_DIR=$TRAVIS_BUILD_DIR pytest -n 4 --doctest-modules --pyargs cartopy;
CARTOPY_GIT_DIR=$TRAVIS_BUILD_DIR pytest -n 4 --doctest-modules --pyargs cartopy --cov=cartopy -ra;
else
CARTOPY_GIT_DIR=$TRAVIS_BUILD_DIR pytest -n 4 --pyargs cartopy;
fi


after_success:
- if [[ "$NAME" == "Latest everything"* ]]; then
coveralls;
fi

after_failure:
- source activate $ENV_NAME
- python -c "from __future__ import print_function; import cartopy.tests.mpl; print(cartopy.tests.mpl.failed_images_html())"
Expand Down
674 changes: 0 additions & 674 deletions COPYING

This file was deleted.

2 changes: 1 addition & 1 deletion INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ The recipes for these can be found at https://github.com/conda-forge/feedstocks.
**Python** 2.7 or later (https://www.python.org/)
Cartopy requires Python 2.7 or later.

**Cython** 0.17 or later (https://pypi.python.org/pypi/Cython/)
**Cython** 0.28 or later (https://pypi.python.org/pypi/Cython/)

**NumPy** 1.10 or later (http://www.numpy.org/)
Python package for scientific computing including a powerful N-dimensional
Expand Down
File renamed without changes.
3 changes: 1 addition & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ include CHANGES
include COPYING*
include INSTALL
include README.rst
include pyproject.toml
include requirements/*.txt
include lib/cartopy/data/*
include lib/cartopy/io/srtm.npz
include lib/cartopy/tests/lakes_shapefile/*
recursive-include lib *.py
recursive-include lib *.pyx *.pxd *.h
recursive-include lib *.pyx *.pxd *.h *.c *.cpp
include versioneer.py
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,21 @@ Documentation can be found at <http://scitools.org.uk/cartopy/docs/latest/>.
- To chat with developers and other users you can use the
[Gitter Chat](https://gitter.im/SciTools/cartopy)

## License and copyright

Cartopy is licensed under GNU Lesser General Public License (LGPLv3).
## Credits, copyright and license

Development occurs on GitHub at <https://github.com/SciTools/cartopy>, with a
contributor's license agreement (CLA) that can be found at
<http://scitools.org.uk/governance.html>.
Cartopy is developed collaboratively under the SciTools umberella.

(C) British Crown Copyright, Met Office
A full list of codecontributors ("Cartopy contributors") can be found at
https://github.com/SciTools/cartopy/graphs/contributors.

Code is just one of many ways of positively contributing to Cartopy, please see
our [contributing guide](.github/CONTRIBUTING.md) for more details on how
you can get involved.

Cartopy is released under a LGPL license with a shared copyright model.
See [LICENSE](LICENSE) for full terms.

The [Met Office](https://metoffice.gov.uk) has made a significant
contribution to the development, maintenance and support of this library.
All Met Office contributions are copyright on behalf of the British Crown.
18 changes: 3 additions & 15 deletions lib/cartopy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
# (C) British Crown Copyright 2011 - 2018, Met Office
# Copyright Cartopy Contributors
#
# This file is part of cartopy.
#
# cartopy is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cartopy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with cartopy. If not, see <https://www.gnu.org/licenses/>.
# This file is part of Cartopy and is released under the LGPL license.
# See LICENSE in the root of the repository for full licensing details.

from __future__ import (absolute_import, division, print_function)

Expand Down
4 changes: 2 additions & 2 deletions lib/cartopy/crs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2011 - 2018, Met Office
# (C) British Crown Copyright 2011 - 2019, Met Office
#
# This file is part of cartopy.
#
Expand Down Expand Up @@ -1177,7 +1177,7 @@ def __init__(self, central_longitude=-96.0, central_latitude=39.0,
self.cutoff = cutoff
n = 91
lons = np.empty(n + 2)
lats = np.full(n + 2, cutoff)
lats = np.full(n + 2, float(cutoff))
lons[0] = lons[-1] = 0
lats[0] = lats[-1] = plat
if plat == 90:
Expand Down
54 changes: 54 additions & 0 deletions lib/cartopy/examples/contour_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Contour labels
--------------
An example of adding contour labels to matplotlib contours.
"""
__tags__ = ['Scalar data']

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

from cartopy.examples.waves import sample_data


def main():
# Setup a global EckertIII map with faint coastlines.
ax = plt.axes(projection=ccrs.EckertIII())
ax.set_global()
ax.coastlines('110m', alpha=0.1)

# Use the waves example to provide some sample data, but make it
# more dependent on y for more interesting contours.
x, y, z = sample_data((20, 40))
z = z * -1.5 * y

# Add colourful filled contours.
filled_c = ax.contourf(x, y, z, transform=ccrs.PlateCarree())

# And black line contours.
line_c = ax.contour(x, y, z, levels=filled_c.levels,
colors=['black'],
transform=ccrs.PlateCarree())

# Uncomment to make the line contours invisible.
# plt.setp(line_c.collections, visible=False)

# Add a colorbar for the filled contour.
plt.colorbar(filled_c, orientation='horizontal')

# Use the line contours to place contour labels.
plt.clabel(
line_c, # Typically best results when labelling line contours.
colors=['black'],
manual=False, # Automatic placement vs manual placement.
inline=True, # Cut the line where the label will be placed.
fmt=' {:.0f} '.format, # Labes as integers, with some extra space.
)

plt.show()


if __name__ == '__main__':
main()
98 changes: 98 additions & 0 deletions lib/cartopy/mpl/contour.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# (C) British Crown Copyright 2011 - 2019, Met Office
#
# This file is part of cartopy.
#
# cartopy is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cartopy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with cartopy. If not, see <https://www.gnu.org/licenses/>.

from __future__ import (absolute_import, division, print_function)

from matplotlib.contour import QuadContourSet
import matplotlib.path as mpath
import numpy as np


class GeoContourSet(QuadContourSet):
"""
A contourset designed to handle things like contour labels.
"""
# nb. No __init__ method here - most of the time a GeoContourSet will
# come from GeoAxes.contour[f]. These methods morph a ContourSet by
# fiddling with instance.__class__.

def clabel(self, *args, **kwargs):
# nb: contour labelling does not work very well for filled
# contours - it is recommended to only label line contours.
# This is especially true when inline=True.

# This wrapper exist because mpl does not properly transform
# paths. Instead it simply assumes one path represents one polygon
# (not necessarily the case), and it assumes that
# transform(path.verts) is equivalent to transform_path(path).
# Unfortunately there is no way to easily correct this error,
# so we are forced to pre-transform the ContourSet's paths from
# the source coordinate system to the axes' projection.
# The existing mpl code then has a much simpler job of handling
# pre-projected paths (which can now effectively be transformed
# naively).

for col in self.collections:
# Snaffle the collection's path list. We will change the
# list in-place (as the contour label code does in mpl).
paths = col.get_paths()

data_t = self.ax.transData
# Define the transform that will take us from collection
# coordinates through to axes projection coordinates.
col_to_data = col.get_transform() - data_t

# Now that we have the transform, project all of this
# collection's paths.
new_paths = [col_to_data.transform_path(path) for path in paths]
new_paths = [path for path in new_paths if path.vertices.size >= 1]

# The collection will now be referenced in axes projection
# coordinates.
col.set_transform(self.ax.transData)

# Clear the now incorrectly referenced paths.
del paths[:]

for path in new_paths:
if path.vertices.size == 0:
# Don't persist empty paths. Let's get rid of them.
continue

# Split the path if it has multiple MOVETO statements.
codes = np.array(
path.codes if path.codes is not None else [0])
moveto = codes == mpath.Path.MOVETO
if moveto.sum() <= 1:
# This is only one path, so add it to the collection.
paths.append(path)
else:
# The first MOVETO doesn't need cutting-out.
moveto[0] = False
split_locs = np.flatnonzero(moveto)

split_verts = np.split(path.vertices, split_locs)
split_codes = np.split(path.codes, split_locs)

for verts, codes in zip(split_verts, split_codes):
# Add this path to the collection's list of paths.
paths.append(mpath.Path(verts, codes))

# Now that we have prepared the collection paths, call on
# through to the underlying implementation.
super(GeoContourSet, self).clabel(*args, **kwargs)
11 changes: 11 additions & 0 deletions lib/cartopy/mpl/geoaxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import matplotlib as mpl
import matplotlib.artist
import matplotlib.axes
import matplotlib.contour
from matplotlib.image import imread
import matplotlib.transforms as mtransforms
import matplotlib.patches as mpatches
Expand All @@ -45,6 +46,7 @@
import cartopy.crs as ccrs
import cartopy.feature
import cartopy.img_transform
import cartopy.mpl.contour
import cartopy.mpl.feature_artist as feature_artist
import cartopy.mpl.patch as cpatch
from cartopy.mpl.slippy_image_artist import SlippyImageArtist
Expand Down Expand Up @@ -1462,6 +1464,10 @@ def contour(self, *args, **kwargs):
result = matplotlib.axes.Axes.contour(self, *args, **kwargs)

self.autoscale_view()

# Re-cast the contour as a GeoContourSet.
if isinstance(result, matplotlib.contour.QuadContourSet):
result.__class__ = cartopy.mpl.contour.GeoContourSet
return result

def contourf(self, *args, **kwargs):
Expand Down Expand Up @@ -1502,6 +1508,11 @@ def contourf(self, *args, **kwargs):
self.dataLim.update_from_data_xy(extent.get_points())

self.autoscale_view()

# Re-cast the contour as a GeoContourSet.
if isinstance(result, matplotlib.contour.QuadContourSet):
result.__class__ = cartopy.mpl.contour.GeoContourSet

return result

def scatter(self, *args, **kwargs):
Expand Down
6 changes: 3 additions & 3 deletions lib/cartopy/tests/crs/test_lambert_conformal.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) British Crown Copyright 2011 - 2018, Met Office
# (C) British Crown Copyright 2011 - 2019, Met Office
#
# This file is part of cartopy.
#
Expand Down Expand Up @@ -72,11 +72,11 @@ def test_single_value(self):
check_proj_params('lcc', crs, other_args)

def test_no_parallel(self):
with pytest.raises(ValueError, message='1 or 2 standard parallels'):
with pytest.raises(ValueError, match='1 or 2 standard parallels'):
ccrs.LambertConformal(standard_parallels=[])

def test_too_many_parallel(self):
with pytest.raises(ValueError, message='1 or 2 standard parallels'):
with pytest.raises(ValueError, match='1 or 2 standard parallels'):
ccrs.LambertConformal(standard_parallels=[1, 2, 3])

def test_single_spole(self):
Expand Down
Loading

0 comments on commit ace4511

Please sign in to comment.