I'm trying to use the Metpy wind barbs feature to overlay wind barbs on a plot with wind speed and topography. For some reason, the wind barbs will not appear on the plot no matter what I do with the zorder or even commenting out the wind speed and topography plot. I define my subplot axis as
ax = fig.add_subplot(111,projection=ccrs.Miller(central_longitude=0.0, globe=None))
Strangely, the wind barbs will appear on a separate subplot if it defined as
ax_barbs = fig.add_subplot(111, projection=ccrs.PlateCarree())
. But if I try making the projection on "ax" as "ccrs.PlateCarree", then the rest of the code doesn't work. Can someone please advise what I am doing wrong? The data is very high resolution so I need to use the Triangulation function to plot my wind speed. This also explains why I want to plot every 1/200 wind barbs in my plot. The full code is below
for i in np.arange(variable.time.size):
fig = plt.figure(figsize=(16, 8))
ax1=fig.add_axes([0.2,0.05,0.6,0.02])
ax = fig.add_subplot(111,projection=ccrs.Miller(central_longitude=0.0, globe=None))
time = data.time[i].values
print(data.time[i].values)
levels = np.linspace(0,35,30)
topo_levels = np.arange(0, 4000, 700)
cmap = plt.cm.get_cmap('BuPu')
#Calculate tri and plot
triang = tri.Triangulation(variable.lon, variable.lat)
cmap = plt.cm.get_cmap('BuPu')
cmap.set_under(color='white')
plot = plt.tricontourf(triang,variable.wind_speed[i,:].data,alpha=0.70,levels=levels,cmap=cmap, transform=ccrs.PlateCarree())
#Add topography info
plot3 = plt.contour(topo.longitude[:],topo.latitude[:],topo.data,levels=topo_levels,colors='0.2',linewidths=0.5,alpha=0.95,transform=ccrs.PlateCarree())
#Add wind barbs
ax.barbs(variable.lon[::200].values, variable.lat[::200].values, variable.u[i,::200].data, variable.v[i,::200].data, color='black', length=5, alpha=0.5,zorder = 7)
#add colorbar
cbar_tickloc = [0,5,10,15,20,25,30,35]
cbar_ticklab = ['0','5','10','15','20','25','30','35']
cb1 = plt.colorbar(plot,extend='both',orientation='horizontal',cax=ax1,shrink=0.8,pad=0.09)
cb1.ax.set_xlabel('wind speed (m s' + r'$^{-1}$)',fontsize=16)
cb1.ax.tick_params(labelsize=16)
cb1.set_ticks(cbar_tickloc)
cb1.ax.set_xticklabels(cbar_ticklab)
ax1.set_position([0.2, 0.25, 0.6, 0.02]) # Adjust these values as needed
ax.set_title('IFS '+str(time)+'',fontsize=18)
ax.coastlines(resolution='10m',linewidth=0.6)
ax.set_extent ((-5, 10, 34, 45), crs=ccrs.PlateCarree())
gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,linewidth=0.7, color='gray', alpha=0.8, zorder=5, linestyle='--') # ax.set_extent([lon[0],lon[1],lat[0],lat[1]], crs=ccrs.PlateCarree())
gl.xlabels_bottom = False
gl.ylabels_right = False
gl.xlocator = mticker.FixedLocator([-10,0,10])
gl.ylocator = mticker.FixedLocator([35,40,45,50,55])
gl.xlabel_style = {'size': 14,}
gl.ylabel_style = {'size': 14,}
lat_formatter = LatitudeFormatter()
ax.yaxis.set_major_formatter(lat_formatter)
lon_formatter = LongitudeFormatter(zero_direction_label=True)
ax.xaxis.set_major_formatter(lon_formatter)
ax.tick_params(labelsize=16)
ax.set_xlabel(None)
ax.set_ylabel(None)
plt.show()
In your other plot methods, you are passing transform=ccrs.PlateCarree()
, which tells Cartopy to interpret the x/y values for that plot method as lon/lat. To get the barbs method to work, you need to do something similar:
ax.barbs(variable.lon[::200].values, variable.lat[::200].values,
variable.u[i,::200].data, variable.v[i,::200].data, color='black',
length=5, alpha=0.5, transform=ccrs.PlateCarree())