4

Я пытаюсь идентифицировать индексы скрытых пикселей при использовании maskoceans , поэтому я могу затем вызывать только пиксели земли в коде, который у меня есть в настоящее время проходит весь земной шар, хотя меня не волнуют океанские пиксели. Я пробовал разные способы сделать это и заметил, что мои сюжеты выглядят действительно странно. В конце концов, я понял, что что-то смешивается с моими индексами lat/lon, хотя я их не трогаю! Вот код:Lat/lon с использованием Basemap и maskoceans, которые смешиваются после цикла «for»

import numpy as np 
import netCDF4 
from datetime import datetime, timedelta 
import matplotlib 
import matplotlib.pyplot as plt 
from matplotlib.ticker import MaxNLocator 
import matplotlib.dates as mpldates 
import heat_transfer_coeffs 
from dew_interface import get_dew 
from matplotlib.dates import date2num, num2date 
import numpy as np 
import netCDF4 
import heat_transfer_coeffs as htc 
from jug.task import TaskGenerator 
import matplotlib.cm as cm 
import mpl_toolkits 
from mpl_toolkits import basemap 
from mpl_toolkits.basemap import Basemap, maskoceans 
np.seterr(all='raise') 

# set global vars 
ifile = netCDF4.Dataset('/Users/myfile.nc', 'r') 
times = ifile.variables['time'][:].astype(np.float64) # hours since beginning of dataset 
lats_1d = ifile.variables['latitude'][:] # 90..-90 
lons_1d = ifile.variables['longitude'][:] # 0..360 
lons_1d[lons_1d>180]-=360 #putting longitude into -180..180 
lons, lats = np.meshgrid(lons_1d, lats_1d) 
ntimes, nlats, nlons = ifile.variables['tm'].shape 
ifile.close() 

map1 = basemap.Basemap(resolution='c', projection='mill',llcrnrlat=-36 , urcrnrlat=10, llcrnrlon=5 , urcrnrlon=52) 
#Mask the oceans 
new_lon = maskoceans(lons,lats,lons,resolution='c', grid = 10) 
new_lat = maskoceans(lons,lats,lats,resolution='c', grid = 10) 

fig = plt.figure 
pc = map1.pcolormesh(lons, lats, new_lat, vmin=0, vmax=34, cmap=cm.RdYlBu, latlon=True) 
plt.show() 

for iii in range(new_lon.shape[1]): 
    index = np.where(new_lon.mask[:,iii] == False) 
    index2 = np.where(new_lon.mask[:,iii] == True) 
    new_lon[index[0],iii] = 34 
    new_lon[index2[0],iii] = 0 

fig = plt.figure 
pc = map1.pcolormesh(lons, lats, new_lat, vmin=0, vmax=34, cmap=cm.RdYlBu, latlon=True) 
plt.show() 

Первая цифра я показывает ожидаемую карту Африки с океанами замаскированы и стоимостью земли, соответствующих широте (до насыщения Colorbar на 34, но это значение было просто принято в качестве пример)

First figure

Однако вторая цифра, которая должна построить точно такую ​​же вещь, как и первый, выходит все перепутались, даже если петля между первым и вторым цифра не коснитесь любого из параметров, связанных с его построением:

Second figure

Если я закомментируйте петлю между фиг.1 и 2, рисунок 2 выглядит так же, как показано на рисунке 1. Любая идея о том, что здесь происходит?

ответ

2

Короткий ответ, ваша петля модифицирует переменные lons и lats косвенно.

Объяснение: функция maskoceans создает массив масок из входного массива. Маскированный массив и входной массив используют одни и те же данные, так что lons и new_lon используют одни и те же данные, то же самое для lats и new_lat. Это означает, что при изменении new_lon в вашем цикле вы также изменяете lons. Это источник вашей проблемы. Единственное отличие состоит в том, что new_lon и new_lat связаны с маской, которая используется для выбора действительных точек данных.

Решение: Сделайте копию исходного массива, прежде чем позвонить maskoceans. Вы можете сделать это с помощью:

import copy 
lons1 = copy.copy(lons) 
lats1 = copy.copy(lats) 

Затем вы используете lons1 и lats1 позвонить maskoceans.

+0

Спасибо за объяснение и исправление, он отлично работает! Я понятия не имел об этой особенности «масок». –

+0

Добро пожаловать! Кстати, эта особенность не от масок, а от базового маскированного массива и от питона вообще, где данные не копируются автоматически в операции присваивания. – innoSPG

+0

Gotcha, спасибо за разъяснение! –