gpt4 book ai didi

python - 具有重新标准化颜色条的 Cartopy pcolormesh

转载 作者:行者123 更新时间:2023-12-01 02:59:06 29 4
gpt4 key购买 nike

我正在尝试绘制全局气溶胶光学深度 (AOD),其值通常约为 0.2,但在某些地区可以达到 1.2 或更高。理想情况下,我想绘制这些高值,而不丢失较小值的细节。对数刻度颜色条也不太合适,因此我尝试使用 docs 中所述的两个线性范围。 :

import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np
import cartopy.crs as ccrs


class MidpointNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
# I'm ignoring masked values and all kinds of edge cases to make a
# simple example...
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
res = np.ma.masked_array(np.interp(value, x, y))
return res

当我尝试使用 Cartopy 绘制 pcolormesh 绘图时,此情况会中断。根据图库示例之一创建虚拟数据:

def sample_data(shape=(73, 145)):
"""Returns ``lons``, ``lats`` and ``data`` of some fake data."""
nlats, nlons = shape
lats = np.linspace(-np.pi / 2, np.pi / 2, nlats)
lons = np.linspace(0, 2 * np.pi, nlons)
lons, lats = np.meshgrid(lons, lats)
wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons)
mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2)

lats = np.rad2deg(lats)
lons = np.rad2deg(lons)
data = wave + mean

return lons, lats, data


ax = plt.axes(projection=ccrs.Mollweide())
lons, lats, data = sample_data()
ax.contourf(lons, lats, data,
transform=ccrs.PlateCarree(),
cmap='spectral', norm=MidpointNormalize(midpoint=0.8))
ax.coastlines()
ax.set_global()
plt.show()

给我这个,看起来不错: working contourf plot

但是,当使用 pcolormesh 等效项似乎不起作用时,它具有一组介于 0 到 180 度经度(图的右半部分)之间的模糊值,而不是等高线图中看到的波浪图案:

ax.pcolormesh(lons, lats, data, 
transform=ccrs.PlateCarree(),
cmap='spectral', norm=MidpointNormalize(midpoint=0.8))

broken pcolormesh plot

如何才能使 pcolormesh 工作?当我对 Cartopy 投影/转换做错事时,我通常会看到这种情况,所以大概这与 Cartopy 环绕日期线的方式或简单的 matplotlib 示例忽略的边缘情况之一有关,但我无法弄清楚出来吧。

请注意,这只在使用自定义规范化实例时才会发生;没有它,pcolormesh 也能按预期工作。

最佳答案

这似乎与规范化类内的屏蔽有关。所以这是一个有效的版本:

class MidpointNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
result, is_scalar = self.process_value(value)
(vmin,), _ = self.process_value(self.vmin)
(vmax,), _ = self.process_value(self.vmax)
resdat = np.asarray(result.data)
result = np.ma.array(resdat, mask=result.mask, copy=False)
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
res = np.interp(result, x, y)
result = np.ma.array(res, mask=result.mask, copy=False)
if is_scalar:
result = result[0]
return result

完整代码:

import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np
import cartopy.crs as ccrs

class MidpointNormalize(colors.Normalize):
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
self.midpoint = midpoint
colors.Normalize.__init__(self, vmin, vmax, clip)

def __call__(self, value, clip=None):
result, is_scalar = self.process_value(value)
(vmin,), _ = self.process_value(self.vmin)
(vmax,), _ = self.process_value(self.vmax)
resdat = np.asarray(result.data)
result = np.ma.array(resdat, mask=result.mask, copy=False)
x, y = [self.vmin, self.midpoint, self.vmax], [0, 0.5, 1]
res = np.interp(result, x, y)
result = np.ma.array(res, mask=result.mask, copy=False)
if is_scalar:
result = result[0]
return result

def sample_data(shape=(73, 145)):
"""Returns ``lons``, ``lats`` and ``data`` of some fake data."""
nlats, nlons = shape
lats = np.linspace(-np.pi / 2, np.pi / 2, nlats)
lons = np.linspace(0, 2 * np.pi, nlons)
lons, lats = np.meshgrid(lons, lats)
wave = 0.75 * (np.sin(2 * lats) ** 8) * np.cos(4 * lons)
mean = 0.5 * np.cos(2 * lats) * ((np.sin(2 * lats)) ** 2 + 2)

lats = np.rad2deg(lats)
lons = np.rad2deg(lons)
data = wave + mean

return lons, lats, data


ax = plt.axes(projection=ccrs.Mollweide())
lons, lats, data = sample_data()

norm = norm=MidpointNormalize(midpoint=0.8)
cm = ax.pcolormesh(lons, lats, data,
transform=ccrs.PlateCarree(),
cmap='spectral', norm=norm )

ax.coastlines()
plt.colorbar(cm, orientation="horizontal")
ax.set_global()
plt.show()

产生

enter image description here

关于python - 具有重新标准化颜色条的 Cartopy pcolormesh,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43984077/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com