Search code examples
matplotlibsubplotcartopy

Add cartopy coastlines to subplots


I am having trouble adding the cartopy coastlines into sublots. For example, ax.coastlines('10m', linewidth = 1.5, color = 'black'). I also want it to match the image extent of the plots. I am plotting a 3d array, where each array on the z axis is a different image. Below is the code

img_extent = (lon.min(), lon.max(), lat.min(), lat.max())

# Create a figure
fig, axarr = plt.subplots(nrows = 4, ncols=4, subplot_kw={'projection': ccrs.PlateCarree()},figsize=(16,14))


# add coastlines
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_extent(img_extent, crs=ccrs.PlateCarree())
ax.coastlines('10m', linewidth=1.5, color = 'black')

# Make the image

axarr[0,0].imshow(first_lag[0],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[0,1].imshow(first_lag[12],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[0,2].imshow(first_lag[24],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[0,3].imshow(first_lag[36],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())

axarr[1,0].imshow(second_lag[0],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[1,1].imshow(second_lag[12],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[1,2].imshow(second_lag[24],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[1,3].imshow(second_lag[36],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())

axarr[2,0].imshow(third_lag[0],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[2,1].imshow(third_lag[12],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[2,2].imshow(third_lag[24],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[2,3].imshow(third_lag[36],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())

axarr[3,0].imshow(third_lag[0],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[3,1].imshow(third_lag[12],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[3,2].imshow(third_lag[24],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())
axarr[3,3].imshow(third_lag[36],  vmin = 0, vmax = 1000, cmap = 'viridis', extent=img_extent, transform=ccrs.PlateCarree())

ax.get_xticks()
#plt.colorbar()
#plt.title(title)

gl = ax.gridlines(color="white", alpha=0.4, linestyle="dotted", draw_labels=True, dms=True, x_inline=False, y_inline=False)
gl.top_labels = False 
gl.right_labels = False 

However the results show this: enter image description here

I want the outline of Puerto Rico on each plot. I am really lost, thank you.


Solution

  • You can compare your code with mine and make correction to yours. Here is my code that works well and produces the plot similar to what you are after.

    import matplotlib.pyplot as plt
    import numpy as np
    import cartopy.crs as ccrs
    
    # settings
    h, w = 12, 10        # for raster image
    nrows, ncols = 3, 2  # array of sub-plots
    figsize = [10, 10]   # figure size, inches
    
    myproj = ccrs.PlateCarree()
    extent = [-68, -65, 16.7, 19.5]
    
    # create figure (fig), and array of axes (ax)
    fig, ax = plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize, subplot_kw={'projection': myproj})
    
    # plot simple raster image on each sub-plot
    for i, axi in enumerate(ax.flat):
        # i runs from 0 to (nrows*ncols-1)
        # axi is equivalent with ax[rowid][colid]
        img = np.random.randint(10, size=(h,w))
        axi.imshow(img, extent=extent, alpha=0.25)
        # get indices of row/column
        rowid = i // ncols
        colid = i % ncols
        # write row/col indices as axes' title for identification
        axi.set_title("Row:"+str(rowid)+", Col:"+str(colid))
        axi.coastlines('50m')
        axi.set_xlim(extent[0], extent[1])
        axi.set_ylim(extent[2], extent[3])
    
        gl = axi.gridlines(color="black", alpha=0.4, linestyle="dotted", draw_labels=True, \
                           dms=False, x_inline=False, y_inline=False)
        gl.top_labels = False 
        gl.right_labels = False 
    
    plt.show()
    

    rico