使用 MetPy 的声明性语法在卫星图像上绘制纬度和经度

问题描述

我试图找到一种方法来可视化 MJO 的各个区域/阶段。我相信这样做的一种方法是绘制分隔每个相位区域的经度线(大约在 60E、80E、100E、120E、140E、160E、180),但我不确定是否可以添加到我现有的地块。

我正在使用来自 NCEI 的 GRID-Sat B1 数据。这是我当前的代码

import matplotlib.pyplot as plt
from metpy.plots import declarative,colortables
import cartopy.crs as ccrs
import xarray as xr

file = "GRIDSAT-B1.2003.11.23.00.v02r01.nc"
dataset = xr.open_dataset(file)
vtime = dataset.time.values.astype('datetime64[s]').astype('O')
date_long = vtime[0]
date = date_long.strftime("%d-%b-%Y-%HZ")

# Create water vapor image
img = declarative.ImagePlot()
img.data = dataset
img.field = 'irwvp'
img.colormap = 'WVCimsS_r'
img.image_range = (180,280)
panel = declarative.MapPanel()
panel.layers = ['coastline','borders']
panel.title = f'GridSat-B1 (Water Vapor Imagery): {date}'
panel.projection = (ccrs.Mollweide(central_longitude=-240))
panel.area = ([-370,-140,-30,30])
panel.layout = (2,1,2)
panel.plots = [img]

# Create the IR image
img2 = declarative.ImagePlot()
img2.data = dataset
img2.field = 'irwin_cdr'
img2.colormap = 'turbo_r' #maybe use cubehelix instead?
img2.image_range = (180,300)
panel2 = declarative.MapPanel()
panel2.layers = ['coastline','borders']
panel2.title = f'GridSat-B1 (Infrared Imagery): {date}'
panel2.projection = (ccrs.Mollweide(central_longitude=-240))
panel2.area = ([-370,30])
panel2.layout = (2,1)
panel2.plots = [img2]

# Plot both panels in one figure
pc = declarative.PanelContainer()
pc.size = (20,14)
pc.panels = [panel,panel2]
pc.show()

这是我运行脚本时创建的当前输出Nov03.png

感谢任何帮助/建议 - 提前致谢!

解决方法

MetPy 的声明式接口没有内置任何内容,但幸运的是 MapPanel 对象公开了一个 .ax 属性,该属性为您提供了一个 Matplotlib Axes 对象及其所有绘图方法:

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import metpy.plots as mpplots
import numpy as np
import xarray as xr

file = "/Users/rmay/Downloads/GRIDSAT-B1.2003.11.23.00.v02r01.nc"
dataset = xr.open_dataset(file)
vtime = dataset.time.values.astype('datetime64[s]').astype('O')
date_long = vtime[0]
date = date_long.strftime("%d-%b-%Y-%HZ")

# Create water vapor image
img = mpplots.ImagePlot()
img.data = dataset
img.field = 'irwvp'
img.colormap = 'WVCIMSS_r'
img.image_range = (180,280)
panel = mpplots.MapPanel()
panel.layers = ['coastline','borders']
panel.title = f'GridSat-B1 (Water Vapor Imagery): {date}'
panel.projection = ccrs.Mollweide(central_longitude=-240)
panel.area = (-370,-140,-30,30)
panel.layout = (2,1,2)
panel.plots = [img]

# Create the IR image
img2 = mpplots.ImagePlot()
img2.data = dataset
img2.field = 'irwin_cdr'
img2.colormap = 'turbo_r' #maybe use cubehelix instead?
img2.image_range = (180,300)
panel2 = mpplots.MapPanel()
panel2.layers = ['coastline','borders']
panel2.title = f'GridSat-B1 (Infrared Imagery): {date}'
panel2.projection = ccrs.Mollweide(central_longitude=-240)
panel2.area = (-370,30)
panel2.layout = (2,1)
panel2.plots = [img2]

# Plot both panels in one figure
pc = mpplots.PanelContainer()
pc.size = (20,14)
pc.panels = [panel,panel2]

lons = np.array([60,80,100,120,140,160,180]).reshape(1,-1)
lats = np.linspace(-90,90).reshape(-1,1)

# Match up the arrays into 2xN arrays fit to plot in call
lons,lats = np.broadcast_arrays(lons,lats)

# Needs to be *after* the panels are assigned to a PanelContainer
# Using Geodetic gives lines interpolated on the curved globe
panel.ax.plot(lons,lats,transform=ccrs.Geodetic(),color='black',linewidth=3)
panel2.ax.plot(lons,linewidth=3)

pc.show()

(注意:不建议直接从 metpy 的声明性模块导入,因为这是一个可能会更改的实现细节——只需从 metpy.plots 获取内容)。所以这是使用 Matplotlib 对 plot 的标准调用来绘制线条。另一种选择是使用 CartoPy 的 Gridliner

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...