NCL_polyg_18.pyΒΆ

This script illustrates the following concepts:
  • Adding lines, markers, and polygons to a map

  • Drawing lines, markers, polygons, and text in inset axes

See following URLs to see the reproduced NCL plot & script:

Import packages:

import cartopy
import cartopy.crs as ccrs
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
import numpy as np
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
from geocat.viz import util as gvutil

Define helper function to remove ticks/frames from axes

def removeTicks(axis):
    axis.get_xaxis().set_visible(False)
    axis.get_yaxis().set_visible(False)

Plot map, markers, and polygons

# Set size of figure
fig = plt.figure(figsize=(10, 10))

# Make grid on figure with 2 rows, 1 column
grid = plt.GridSpec(2, 20, figure=fig)

# Make subplot for map
ax = plt.subplot(grid[:-1, 1:], projection=ccrs.PlateCarree())

# Add continents
continents = cartopy.feature.NaturalEarthFeature(name='land',
                                                 category='physical',
                                                 scale='50m',
                                                 edgecolor='None',
                                                 facecolor='lightgray')

ax.add_feature(continents)

# Set map extent
ax.set_global()

# Create arrays with location of each marker
lon = np.arange(-160, 160, 20)
lat = np.arange(-80, 80, 10)

# Create array with marker symbols
# Matplotlib provides a different set of markers than NCL, so plot appearance differs
marker = [
    '.', '+', '*', 'o', 'x', 's', '^', 'v', 'D', '>', '<', 'p', 'h', '8', 'X',
    'd'
]

# Draw markers on diagonal line across graph
for x in range(len(lon)):
    ax.plot(lon[x],
            lat[x],
            marker=marker[x],
            color='blue',
            fillstyle='none',
            markersize=18,
            zorder=3)

# Draw small red box in upper center
ax.add_patch(
    mpatches.Rectangle(xy=[7, 47],
                       width=9,
                       height=7,
                       facecolor='None',
                       edgecolor='red',
                       alpha=1.0,
                       transform=ccrs.PlateCarree(),
                       zorder=5))

# Draw green window in bottom right
ax.add_patch(
    mpatches.Rectangle(xy=[110, -45],
                       width=50,
                       height=35,
                       facecolor='lime',
                       alpha=0.3,
                       transform=ccrs.PlateCarree(),
                       zorder=5))

# Use gvutil function to set the ticks on axes
gvutil.set_axes_limits_and_ticks(ax,
                                 xlim=None,
                                 ylim=None,
                                 xticks=np.arange(-180, 210, 30),
                                 yticks=np.arange(-90, 120, 30),
                                 xticklabels=None,
                                 yticklabels=None)

# Use gvutil function to give ticks W/N/E/S labels
gvutil.add_lat_lon_ticklabels(ax,
                              zero_direction_label=True,
                              dateline_direction_label=True)

# Took out degree symbols in latitude/longitude
ax.yaxis.set_major_formatter(LatitudeFormatter(degree_symbol=''))
ax.xaxis.set_major_formatter(LongitudeFormatter(degree_symbol=''))

# Use gvutil function to set title of plot
# Set title font to bold using the r"$\bf{_____}$" formatting characters
# Spaces in title will not show up if included in curly brackets
gvutil.set_titles_and_labels(ax,
                             maintitle=r"$\bf{Big}$" + " " +
                             r"$\bf{centered}$" + " " + r"$\bf{title}$",
                             maintitlefontsize=25)

# Use gvutil function to plot three minor ticks for every major tick on axes
gvutil.add_major_minor_ticks(ax,
                             x_minor_per_major=3,
                             y_minor_per_major=3,
                             labelsize="small")

# Make second subplot for legend
ax2 = plt.subplot(grid[-1, 1:], frameon=False)
removeTicks(ax2)

# Create 6 inset axes within subplot for each field in legend
# Inset_axes positional array argument takes four values:
# [starting (bottom left) x coordinate of window, starting y coordinate of window, width of field, height of field]

# Add circle
axin1 = ax2.inset_axes([0.1, 0.8, .1, .1], frameon=False)
removeTicks(axin1)
axin1.add_patch(mpatches.Circle((0.1, 0.1), radius=.1, color='blue'))
axin1.axis('equal')

# Add label for circle
axin2 = ax2.inset_axes([0.0, 0.65, .20, .5], frameon=False)
removeTicks(axin2)
axin2.text(0,
           .7,
           'Marker (left justified text)',
           color='blue',
           fontsize=12,
           verticalalignment='center')

# Add red line
axin3 = ax2.inset_axes([0.30, 0.6, .33, .5], frameon=False)
removeTicks(axin3)
axin3.plot([0, 4], [3, 3], color='red')
axin1.axis('scaled')

# Add label for red line
axin4 = ax2.inset_axes([0.33, 0.65, .33, .5], frameon=False)
removeTicks(axin4)
axin4.text(0,
           .7,
           'Polyline (centered text)',
           color='red',
           fontsize=12,
           verticalalignment='center')

# Add green polygon
axin5 = ax2.inset_axes([0.62, 0.6, .33, .5], frameon=False)
removeTicks(axin5)
axin5.add_patch(
    mpatches.Rectangle(xy=[.3, .3],
                       width=.6,
                       height=.3,
                       facecolor='lime',
                       alpha=0.3))
axin1.axis('scaled')

# Add label for green polygon
axin6 = ax2.inset_axes([0.66, 0.65, .33, .5], frameon=False)
removeTicks(axin6)
axin6.text(0,
           .7,
           'Polygon (right justified text)',
           color='lime',
           fontsize=12,
           verticalalignment='center')

plt.show()
$\bf{Big}$ $\bf{centered}$ $\bf{title}$

Total running time of the script: ( 0 minutes 0.755 seconds)

Gallery generated by Sphinx-Gallery