Данные о погоде на картах

Я пытаюсь нанести некоторые данные о погоде на карту, используя Basemap (я также готов попробовать cartopy) на Python. Сейчас мои данные о погоде выглядят так: этим. Мой источник данных в основном представляет собой массив, в котором каждая позиция соответствует квадрату сетки, а каждое значение указывает цвет, которым должен быть этот квадрат. Код, используемый для создания этого изображения, выглядит следующим образом, где каждый квадрат сетки равен 1000 м:

grid_0 = np.asarray(dec.split())
grid_1=np.reshape(grid_0,(n_cols,n_rows))
grid_2 = grid_1.astype(float)

# Make plot
plt.figure(figsize=(30,30))
fig, ax = plt.subplots()

plt.axis('off')
cax = ax.imshow(grid_2, interpolation='nearest', cmap=cmap)

У меня есть информация о том, где географически расположен нижний угол сетки. Я считаю, что лучший способ отобразить это на карте — это каким-то образом использовать функцию контура (), но я совершенно новичок в базовой карте и не могу найти способ преобразовать это во что-то, что может понять контурная функция (). Для наложения карты я использую Basemap, где lon_air и lat_air — координаты определенного аэропорта:

fig=figure(1, figsize=(19, 15))

m = Basemap(projection='cyl', llcrnrlon=lon_air-25, llcrnrlat=lat_air-15,
            urcrnrlon=lon_air+25, urcrnrlat=lat_air+15, resolution='h', area_thresh=10000)

m.drawstates(linewidth=0.5, color='black', zorder=4)
m.drawcountries(linewidth=2.0, color='white', zorder=3)
m.drawmapboundary(fill_color='#e5f5ff')
m.fillcontinents(color='#DFDFDF', zorder=1)
m.scatter(lon_air, lat_air,marker='o',color='k', zorder=10)

x0, y0 = lon_air-((360*920)/(4*np.pi*6371)),lat_air-((360*920)/(4*np.pi*6371)) 
x1, y1 = lon_air+((360*920)/(4*np.pi*6371)), lat_air+((360*920)/(4*np.pi*6371)) 

im = plt.imshow(plt.imread('./pngs/9905.png'), extent=(x0, x1, y0, y1), zorder=2)
plt.show()

Я отредактирую сообщение, если кто-то посчитает нужным больше деталей. Заранее спасибо всем!


person Guillermo Moreno Castaño    schedule 31.08.2018    source источник
comment
какой код у вас есть, чтобы генерировать данные о погоде и карту отдельно? Если мы увидим, что сможем лучше помочь вам объединить два   -  person Aaron    schedule 31.08.2018
comment
Как сказал Аарон, наличие кода в вопросе может помочь вам получить ответ. Похоже, вы пытаетесь построить некоторые данные радара с предоставленной фотографии. Я бы посмотрел на metpy (ссылка на документы) и посмотрел, есть ли что-нибудь там, что может относиться к вам.   -  person Brandon Molyneaux    schedule 01.09.2018
comment
Спасибо за ваши комментарии, ребята, я отредактировал свой вопрос и прямо сейчас проверю MetPy :)   -  person Guillermo Moreno Castaño    schedule 03.09.2018


Ответы (1)


Создание графика Basemap.contourf — довольно стандартная процедура. Ваша команда plt.imread должна вернуть вам 2D-массив numpy (при условии, что это оттенки серого), поэтому сделайте что-то вроде этого, чтобы получить фактические данные и их размеры:

data = plt.imread('./pngs/9905.png')
lx, ly = data.shape

Далее вам нужно указать координаты для каждой точки ваших данных. Для contourf это делается с помощью двух дополнительных 2D-полей, одно с координатами x и одно с координатами y. Вы можете получить правильную форму с помощью np.linspace и np.meshgrid:

lon0, lat0 = lon_air-((360*920)/(4*np.pi*6371)),lat_air-((360*920)/(4*np.pi*6371))
lon1, lat1 = lon_air+((360*920)/(4*np.pi*6371)), lat_air+((360*920)/(4*np.pi*6371))
lons = np.linspace(lon0, lon1, lx)  #1D
lats = np.linspace(lat0, lat1, ly)  #1D
lon, lat = np.meshgrid(lons,lats)   #1D --> 2D

Теперь вам все еще нужно преобразовать координаты вашей карты в координаты проекции, а затем построить все это:

x,y = m(lon, lat)
m.contourf(x,y,data)
plt.show()

Могут быть некоторые проблемы с расположением данных (иногда это немного сбивает с толку), поэтому вам, возможно, придется транспонировать их (data.T) или инвертировать измерение (путем индексации [::-1]). Если вы столкнетесь с такими проблемами, спросите (или предоставьте пример изображения), тогда я смогу соответствующим образом скорректировать ответ. О, и не забудьте добавить

import numpy as np

где-то в начале вашего скрипта.

person Thomas Kühn    schedule 06.09.2018
comment
Спасибо, Томас, это самое близкое, что я получил к желаемому продукту. Изображение не черно-белое, поэтому я получаю трехмерный массив с lz=4, который, как мне кажется, вызывает у меня проблемы. Мне удалось напечатать тот же grid_3, но я получил белый фон, которого там быть не должно. При использовании fig = plt.figure() m = [...] x,y = m(долгота, широта) m.contourf(x,y,data, zorder=10, cmap=cmap) img=plt.show( ) fig.savefig('./9905/each'.png') Я получаю: ValueError: операнды не могут быть переданы вместе с фигурами (993,1032,4) (1032,993) И с data.t: Input z must быть двумерным массивом. - person Guillermo Moreno Castaño; 06.09.2018
comment
@GuillermoMorenoCastaño Если данные, которые вы получаете от plt.imread(), имеют z-размер 4, это означает, что ваше изображение является изображением rgba, например. три цветовых канала и альфа-канал. В этом случае вам сначала нужно подумать, что эти цвета и альфа-канал означают с точки зрения представления данных. Я предполагаю, что ваше изображение уже представляет собой псевдоцветное изображение (будь то контурный график или что-то еще), что означает, что вы, вероятно, хотите только наложить изображение на карту, а не использовать pyplot.contourf() в все... - person Thomas Kühn; 06.09.2018
comment
...здесь обсуждается использование Basemap.imshow(), но, видимо, это работает только для цилиндрических карт. Есть ли способ получить данные о погоде в виде реальных данных, а не изображения? - person Thomas Kühn; 06.09.2018