Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weather data over maps

I am trying to plot some weather data over a map using Basemap (I'm open to trying cartopy also) on Python. Right now, my weather data looks like this. My data source is basically an array with each position corresponding to a square of the grid and each value indicating the color that square should be. The code used to generate this image looks like this, where each square of the grid equals to 1000 m:

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)

I have the information on where geographically the lower corner of the grid is located. I believe that the best way of plotting this on a map is somehow using the contourf() function, but I'm quite new to Basemap and can't find a way of transforming this to something that contourf() can understand. To lpot the map I'm using Basemap, where lon_air and lat_air are the coordinates of a certain airport:

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

I will edit the post if somebody think that more details are needed. Thanks in advance to everyone!

like image 623
Guillermo Moreno Castaño Avatar asked Mar 07 '26 02:03

Guillermo Moreno Castaño


1 Answers

Producing a Basemap.contourf plot is a pretty standard procedure. Your plt.imread command should return you a 2D numpy array (assuming it is grey scale), so do something like this to get the actual data and its dimensions:

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

Next you need to provide coordinates for each point of your data. For contourf this is done providing two additional 2D fields, one with the x-coordinates and one with the y-coordinates. You can get the right form with np.linspace and 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

Now you still need to convert your map coordinates into projection coordinates and then plot the whole thing:

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

There may be still some issues with the arrangement of the data (it's sometimes a bit confusing), so you might have to transpose it (data.T) or invert a dimension (by indexing [::-1]). If you run into these kind of problems, please ask (or provide an example image), then I can adjust the answer accordingly. Oh, and remember to add a

import numpy as np

somewhere in the beginning of your script.

like image 194
Thomas Kühn Avatar answered Mar 08 '26 15:03

Thomas Kühn