2017-05-15 1 views
1

전 세계 Aerosol Optical Depth (AOD)를 플롯하려고하는데 일반적으로 값은 약 0.2이지만 일부 지역에서는 1.2 이상이 될 수 있습니다. 이상적으로는 작은 값의 세부 정보를 손실하지 않고 이러한 높은 값을 플로팅하고 싶습니다. 로그 스케일 컬러 바는 하나 정말 적절하지 않다, 그래서 docs에 설명 된대로 두 개의 선형 범위를 사용하여 시도했다 : 그래도 Cartopy와 pcolormesh 플롯을하려고 할 때다시 정규화 된 컬러 바를 사용하는 카피 본 pcolormesh

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 

이 나옵니다. 갤러리 예제 중 하나에 따라 더미 데이터 생성 : 작동하지 않는 pcolormesh 동등한를 사용하는 경우에는 working contourf plot

는, 그것이 번지 세트가 :

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() 

것은 나에게 확인을 보이는이, 부여

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

broken pcolormesh plot

,617 : 윤곽 플롯에서 볼 0과 180 도의 경도 (플롯의 우측 절반) 대신 파형 패턴 사이의 값

어떻게하면 pcolormesh에서이 작업을 수행 할 수 있습니까? 나는 Cartopy 프로젝션/변형에 문제가 생겼을 때 이것을 보았을 것입니다. 아마도 이것은 Cartopy가 dateline이나 간단한 matplotlib 예제가 무시하는 가장자리를 감싸는 방식과 관련이 있습니다. 그것.

사용자 지정 정규화 인스턴스를 사용할 때만 발생합니다. 그것 없이도 pcolormesh는 예상대로 작동합니다.

+0

생산이 @ImportanceOfBeingErnest pcolormesh 예 (두 번째 플롯)가 지저분 세트가 그래서 여기 가 작동하는 버전입니다 등고선 플롯에서 볼 수있는 물결 모양 패턴 대신 경도 0에서 180 사이의 값입니다. 나는 Cartopy projection/transformation을 잘못했을 때 이것을 볼 수있다. –

+0

OK, thanks. 나는 질문을 편집하여 더 명확하게 만들었습니다. 0-180도 경도는 플롯의 오른쪽 절반이며, 왼쪽 절반과 대칭이어야합니다 (등고선 플롯이 있음). –

+0

예, MidpointNormalize를 사용하여 색상 스케일을 표준화 할 때만 사용됩니다. 그래, 그럴거야 ...! –

답변

2

정규화 클래스 내부의 마스킹과 관련이있는 것 같습니다.

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

관련 문제