Daniel Watkins
Daniel Watkins

Reputation: 1701

Problems with pcolormesh in Cartopy

I'm trying to adapt the Cartopy example plot for circular South Polar Stereographic plots to the North Pole and add data to it. I have a couple questions.

First, in the example code, the land feature is added before the ocean feature. When I did that, I got a map with only ocean. I reversed the order of the call in the code below and get a map with land and ocean. Why did the other order work with the South Polar example?

Second, and more importantly, I can't figure out why my pcolormesh call isn't having any effect.

I'm using Python 2.7.7, matplotlib 1.5.1, and Cartopy 0.15.1.

import matplotlib.path as mpath
import matplotlib.pyplot as plt
import numpy as np

import cartopy.crs as ccrs
import cartopy.feature

lats = np.linspace(60,90,30)
lons = np.linspace(0,360,200)
X,Y = np.meshgrid(lons,lats)
Z = np.random.normal(size = X.shape)

def main():
    fig = plt.figure(figsize=[10, 5])
    ax = plt.subplot(1, 1, 1, projection=ccrs.NorthPolarStereo())
    fig.subplots_adjust(bottom=0.05, top=0.95,
                        left=0.04, right=0.95, wspace=0.02)

    # Limit the map to -60 degrees latitude and below.
    ax.set_extent([-180, 180, 60, 60], ccrs.PlateCarree())

    ax.gridlines()

    ax.add_feature(cartopy.feature.OCEAN)
    ax.add_feature(cartopy.feature.LAND)

    # Compute a circle in axes coordinates, which we can use as a boundary
    # for the map. We can pan/zoom as much as we like - the boundary will be
    # permanently circular.
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)

    ax.set_boundary(circle, transform=ax.transAxes)
    ax.pcolormesh(X,Y,Z,transform=ccrs.PlateCarree())


    plt.show()


if __name__ == '__main__':
    main()

Upvotes: 4

Views: 5392

Answers (1)

swatchai
swatchai

Reputation: 18762

Your code leaves cartopy to dictate the order of feature plots on the map, as a result, some features can be hidden with no clues. It is possible to specify the order of plots explicitly.

The order of features plot is controlled by zorder, which can be specified with zorder=integer in most plotting statements. Here is a modified code that produces a better plot.

# your data
lats = np.linspace(60, 90, 30)
lons = np.linspace(0, 360, 160)
X,Y = np.meshgrid(lons, lats)
Z = np.random.normal(size = X.shape)

# new data for pcolormesh plot
latz = np.linspace(75, 90, 15)
lonz = np.linspace(0, 360, 160)
X1,Y1 = np.meshgrid(lonz, latz)
Z1 = np.random.normal(size = X1.shape)

def main():
    fig = plt.figure(figsize=[10, 10])
    ax = plt.subplot(1, 1, 1, projection=ccrs.NorthPolarStereo())
    fig.subplots_adjust(bottom=0.05, top=0.95,
                        left=0.04, right=0.95, wspace=0.02)

    # Limit the map to -60 degrees latitude and below.
    ax.set_extent([-180, 180, 60, 60], ccrs.PlateCarree())

    ax.gridlines()

    # zorder can be used to arrange what is on top
    ax.add_feature(cartopy.feature.LAND, zorder=4)   # land is specified to plot above ...
    ax.add_feature(cartopy.feature.OCEAN, zorder=1)  # ... the ocean

    # Compute a circle in axes coordinates, which we can use as a boundary
    # for the map. We can pan/zoom as much as we like - the boundary will be
    # permanently circular.
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)

    ax.set_boundary(circle, transform=ax.transAxes)
    # pcolormesh is specified to plot on top of the ocean but below land
    ax.pcolormesh(X1, Y1, Z1, transform=ccrs.PlateCarree(), zorder=3)

    plt.show()

if __name__ == '__main__':
    main()

enter image description here

Upvotes: 4

Related Questions