Sedighe
Sedighe

Reputation: 9

How to plot streamlines with netcdf data in python using cartopy or basemap?

I wanted to plot streamlines with NOAA from composite (2.5*2.5 lon/lat). I tried to draw it with basemap (The codes are attached) but I face to this error: 'y' must be strictly increasing. After that, I decided to draw it with cartopy (The codes are attached) with (crs=ccrs.PlateCarree(central_longitude=180). The streamlines in the range of 160 east to 160 west were not drawn. Of course, with this wind data, I drew the vector wind in the basemap using this code: plt.quiver(lon[::5],lat[::5],U4[0,::5,::5],V4[0,::5,::5],scale_units='xy',scale=0.25) but I received an error for drawing the streamline. I would be very grateful if someone could help me solve this problem (with basemap or cartopy). My codes attempting to solve the problem:

from netCDF4 import Dataset as NetCDFFile 
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap

fig = plt.figure(figsize=(12,9))
ax = fig.add_subplot(111)
nc2 = NetCDFFile('E:/cycle-of-Mjo/NOAA/nc/u850b1.nc')
nc4 = NetCDFFile('E:/cycle-of-Mjo/NOAA/nc/v850b1.nc')
lat = nc2.variables['lat'][:]
lon = nc2.variables['lon'][:]
U4 = nc2.variables['uwnd'][:]
V4 = nc4.variables['vwnd'][:]
map = Basemap(projection='cyl', lon_0 =0 , lat_0 =-20 , 
llcrnrlon=0.,llcrnrlat=-20.,urcrnrlon=360.,urcrnrlat=61.,resolution='i' 
,suppress_ticks=False)
plt.tick_params(labelleft=False, labelbottom=False , axis='both',which='major')
map.drawcoastlines()
parallels = np.arange(-20.,61.,20.)
meridians = np.arange(0,360.,50.)
map.drawparallels(lat_ticks,labels=[0,0,0,0],fontsize=10 , dashes=(0,1), fontweight='bold')
map.drawmeridians(lon_ticks,labels=[0,0,0,0],fontsize=10 , dashes=(0,1), fontweight='bold')
lons,lats= np.meshgrid(lon,lat)
x,y = map(lons,lats)
map.streamplot(x,y,U1[0, :, :],V1[0, :, :],density = 2)
**Error:'y' must be strictly increasing**

With Cartopy:

from netCDF4 import Dataset as NetCDFFile 
import numpy as np  
import cartopy.crs as ccrs 
import matplotlib.pyplot as plt
import cartopy.mpl.ticker as cticker
from cartopy.mpl.ticker import LatitudeFormatter, LongitudeFormatter
from cartopy.mpl.gridliner import LongitudeFormatter

nc2 = NetCDFFile('E:/cycle-of-Mjo/NOAA/nc/u850b1.nc')
nc4 = NetCDFFile('E:/cycle-of-Mjo/NOAA/nc/v850b1.nc')
lat = nc2.variables['lat'][:]
lon = nc2.variables['lon'][:]
U4 = nc2.variables['uwnd'][:]
V4 = nc4.variables['vwnd'][:]
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180.0))
ax.coastlines()
ax.set_extent([0, 360, -20, 60], crs=ccrs.PlateCarree())  
ax.set_xticks(np.arange(0,360,50), crs=ccrs.PlateCarree())
strm = plt.streamplot(lon[::5], lat[::5], U1[0,::5,::5], V1[0,::5,::5], color='blue', 
density=1,arrowstyle='->', arrowsize=1, transform=ccrs.PlateCarree() )  
plt.show() 

enter image description here

Upvotes: 0

Views: 91

Answers (1)

Beinje
Beinje

Reputation: 626

The input NetCDF gridded data has probably latitude values ranged from North to South, thus sorted by decreasing values.

But streamplot() is expecting x and y arrays sorted in ascending order, as stated in the doc here

Evenly spaced strictly increasing arrays to make a grid

So you should just sort the latitude array like this:

lat = nc2.variables['lat'][:][::-1]

This will reverse the order of your list and range the latitude values from South to North.

Of course, you will also have to rearrange your U and V arrays accordingly so that the wind values fit your new grid.

Upvotes: 0

Related Questions