Matplotlib / CartoPy Solid Заполнение под контурным графиком - PullRequest
0 голосов
/ 04 апреля 2020

Я хочу добавить заполнение solid под мои контурные данные (контур в Matplotlib). В частности, я бы хотел, чтобы заполнение solid было ограничено указанием c шейп-файлов, в данном случае отдельных штатов в континентальной части США.

Мой текущий сюжет

Current Contoured Plot

Мой текущий код

Обратите внимание, что я включил ключевые внутренние операции для построения контуров и шейп-файлов, я исключил посторонний код (например, городские графики), чтобы помочь тем, кто работает над решением этого вопроса.

import os, sys, re, ast, tifffile
import matplotlib.pyplot as plt
import matplotlib.colors as clr
import matplotlib.figure as fig
import matplotlib as mpl
import cartopy.crs as crs
import cartopy.feature as cfeature
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature

states = '/filepath/gis/st_us.shp'
counties = '/filepath/gis/cnt_us.shp'
lakes_hires = '/filepath/gis/lk_us.shp'
states_feature = ShapelyFeature(Reader(states).geometries(), crs.LambertConformal(), facecolor='none', edgecolor='black')
states_fill = ShapelyFeature(Reader(states).geometries(), crs.LambertConformal(), facecolor='#C7C6C1', edgecolor='none')
counties_feature = ShapelyFeature(Reader(counties).geometries(), crs.LambertConformal(), facecolor='none', edgecolor='lightgray')
lakeshi_feature = ShapelyFeature(Reader(lakes_hires).geometries(), crs.LambertConformal(), facecolor='none', edgecolor='navy')

file = '/filepath/gis/globalpop_conus_1km.tif'
tiffimage = tifffile.imread(file)
lat0 = 52.817021799999999
lon0 = -130.122944799999999 
dlat = 0.008332904595765
dlon = 0.008332442558080
tiffimage[tiffimage<-1e100]=np.nan
tiffimage[tiffimage>1e100]=np.nan
tiflats = np.linspace(lat0,(lat0 - (tiffimage.shape[0]*dlat)),num=tiffimage.shape[0])
tiflons = np.linspace(lon0,(lon0 + (tiffimage.shape[1]*dlon)),num=tiffimage.shape[1])
tiffgrid = np.meshgrid(tiflats,tiflons)
tiffimage = tiffimage.transpose()
xtif,ytif = tiffgrid[1],tiffgrid[0]

fig = plt.figure(figsize=(14,8))
ax = plt.axes([0.25, 0.05, 0.95, 0.9],projection=crs.LambertConformal())
ax.set_adjustable('datalim')
ax.set_extent(lit_domain, crs=crs.LambertConformal())

ax.add_feature(counties_feature, linewidth=0.75)
ax.add_feature(states_feature, linewidth=1.75)

vals=[1, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000]
cmap = clr.LinearSegmentedColormap.from_list('Population',[(0, '#1e6eeb'), (0.15, '#e1ffff'),(0.25, '#0fa00f'),(0.255, '#fffaaa'),(0.40, '#e11400'),(0.55, '#78000c'),(0.79, '#e96f58'),(0.80, '#643c32'),(1, '#f0dcd2')], N=256)
bounds=[1, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000]

norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

im = plt.contourf(xtif, ytif, tiffimage, levels=vals, cmap=cmap, norm=norm, alpha=0.85, transform=crs.LambertConformal())

plt.colorbar(im, pad=0.01, boundaries=[1, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000], ticks=[1, 10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000, 25000, 30000, 35000, 40000, 45000, 50000], spacing='uniform', aspect=40)

Мой первоначальный подход

Мой первоначальный подход заключался в выполнении следующих строк кода (не показано выше, поскольку он не дал желаемого результата)

states_fill = ShapelyFeature(Reader(states).geometries(), crs.LambertConformal(), facecolor='#C7C6C1', edgecolor='none')
ax.add_feature(states_fill, linewidth=1.75)
im = plt.contourf(xtif, ytif, tiffimage, levels=vals, cmap=cmap, norm=norm, alpha=0.85, transform=crs.LambertConformal())

С добавлением и размещением ax.add_feature(states_fill, linewidth=1.75) был нанесен серый заполненный шейп-файл всех штатов США, что было ожидаемо и желательно. Тем не менее, он поместил этот шейп-файл над контурным графиком, хотя я правильно его упорядочил до выполнения plt.contourf.

Как лучше всего разместить закрашенный контур под контурным графиком? Любая помощь с благодарностью!

1 Ответ

0 голосов
/ 05 апреля 2020

Это была сложная, хитрая проблема, однако есть очень простое добавление к графическим шейп-файлам под контурным изображением:

ax.add_feature(states_fill, linewidth=0.45, zorder=0)

Обратите внимание на добавление zorder=0. Это обеспечит построение шейп-файлов, которые должны находиться на нижнем / нижнем слое графика, соответственно.

...