def plot_sfwind(): print(" 10M WIND") # Set Figure Size (1000 x 800) plt.figure(figsize=(width,height),frameon=False) # Convert winds from m/s to kts and then draw barbs u_wind_kts = u_wind_ms[time] * 1.94384449 v_wind_kts = v_wind_ms[time] * 1.94384449 windmag = np.power(np.power(u_wind_kts,2)+np.power(v_wind_kts,2), 0.5) WIND_LEVS = range(10,46,2) W=plt.contourf(x,y,windmag,WIND_LEVS,extend='max') plt.barbs(x_th,y_th,u_wind_kts[::thin,::thin],\ v_wind_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') # Convert Surface Pressure to Mean Sea Level Pressure stemps = temps[time]+6.5*nc.variables['HGT'][time]/1000. mslp = nc.variables['PSFC'][time]*np.exp(9.81/(287.0*stemps)*nc.variables['HGT'][time])*0.01 + (6.7 * nc.variables['HGT'][time] / 1000) # Contour the pressure #PLEVS = range(900,1050,5) #P=plt.contour(x,y,mslp,PLEVS,V=2,colors='k',linewidths=1.5) #plt.clabel(P,inline=1,fontsize=8,fmt='%1.0f',inline_spacing=1) title = 'Sfc MSLP (mb), 10m Wind (kts)' prodid = 'wind' units = "kts" drawmap(W, title, prodid, units)
def mapWind(nest, time): """Creates a map of the domain, showing wind barbs for the given time """ nc = openWRF(nest) nc1 = openWRF(nest + 1) Nx, Ny, _Nz, longitude, latitude, _dx, _dy, _x, _y = getDimensions(nc) m = _getMapForNC(nc, False, _getDL(nest), 100) _makeDots(m) u10 = nc.variables["U10"][time, :, :] v10 = nc.variables["V10"][time, :, :] # Use data from every 10th grid point windx = 1 + Nx / 10 windy = 1 + Ny / 10 lat10 = np.zeros((windy, windx)) lon10 = np.zeros((windy, windx)) uwind = np.zeros((windy, windx)) vwind = np.zeros((windy, windx)) for j in range(windy): for i in range(windx): uwind[j, i] = 0.5 * (u10[j * 10, i * 10] + u10[j * 10, i * 10 + 1]) # print 'u: ' + str(uwind[j,i]) vwind[j, i] = 0.5 * (v10[j * 10, i * 10] + v10[j * 10 + 1, i * 10]) # print 'v: ' + str(vwind[j,i]) lat10[j, i] = latitude[j * 10, i * 10] lon10[j, i] = longitude[j * 10, i * 10] x10, y10 = m(lon10, lat10) plt.barbs(x10, y10, uwind, vwind, barb_increments=barb_increments, linewidth=1.0, color="green") if nc1 is not None: _plotBorder(nc1, m, "black") plt.show() plt.close()
def plot_srhel(): print(" SR Helicity") # Set Figure Size (1000 x 800) plt.figure(figsize=(width,height),frameon=False) P = nc.variables['P'] PB = nc.variables['PB'] UU = nc.variables['U'] VV = nc.variables['V'] PH = nc.variables['PH'] PHB = nc.variables['PHB'] # Need pressures, temps and mixing ratios PR = P[time] + PB[time] PHT = np.add(PH[time],PHB[time]) ZH = np.divide(PHT, 9.81) U = UU[time] V = VV[time] for j in range(len(U[1,:,1])): curcol_c = [] curcol_Umo = [] curcol_Vmo = [] for i in range(len(V[1,1,:])): sparms = severe.SRHEL_CALC(U[:,j,i], V[:,j,i], ZH[:,j,i], PR[:,j,i]) curcol_c.append(sparms[0]) curcol_Umo.append(sparms[1]) curcol_Vmo.append(sparms[2]) np_curcol_c = np.array(curcol_c) np_curcol_Umo = np.array(curcol_Umo) np_curcol_Vmo = np.array(curcol_Vmo) if j == 0: srhel = np_curcol_c U_srm = np_curcol_Umo V_srm = np_curcol_Vmo else: srhel = np.row_stack((srhel, np_curcol_c)) U_srm = np.row_stack((U_srm, np_curcol_Umo)) V_srm = np.row_stack((V_srm, np_curcol_Vmo)) #print " SRHEL: ", np.shape(srhel) # Now plot SRHEL_LEVS = range(50,800,50) srhel = np.nan_to_num(srhel) SRHEL=plt.contourf(x,y,srhel,SRHEL_LEVS) u_mo_kts = U_srm * 1.94384449 v_mo_kts = V_srm * 1.94384449 plt.barbs(x_th,y_th,u_mo_kts[::thin,::thin],\ v_mo_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') title = '0-3 km SRHelicity, Storm Motion (kt)' prodid = 'hlcy' units = "m" + u'\u00B2' + '/s' + u'\u00B2' drawmap(SRHEL, title, prodid, units)
def windbarbs(self,nc,time,y,x,P,thin_locs,n=45.0,color='black'): uwind = 0.5*(nc.variables['U'][time,:,y,x]+nc.variables['U'][time,:,y,x+1]) vwind = 0.5*(nc.variables['V'][time,:,y,x]+nc.variables['V'][time,:,y+1,x]) zmax = len(uwind[thin_locs]) delta = 1 baraxis = [n for _j in range(0,zmax,delta)] # pdb.set_trace() plt.barbs(baraxis,P[thin_locs],uwind[thin_locs],vwind[thin_locs], barb_increments=self.barb_increments, linewidth = .75,color=color)
def plot_vector_barbs(velocity_radial_f, azimuth, ranges, r, e, u, v): ran, theta = np.meshgrid(ranges[r], azimuth[e,:]) plt.figure() plt.subplot(111, polar=True) plt.barbs(u[e,:,r], v[e,:,r], ran, theta) plt.show() #plt.savefig('Radar_Qxb_Band_S - Barbs ({:.2f} km Range) ME.png'.format((r*1498)/1000.), format='png') plt.close()
def windbarbs_real(self,uwind,vwind,P,delta=3,color='red',n=37.5): # Is wind in kt or m/s? .... uwind* those = N.where(uwind==-9999) # Find nonsense values uwind = N.delete(uwind,those) vwind = N.delete(vwind,those) P = N.delete(P,those) zmax = len(uwind) # n is x-ax position on skewT for barbs. baraxis = [n for _j in range(0,zmax,delta)] plt.barbs(baraxis,P[0:zmax:delta],uwind[0:zmax:delta],vwind[0:zmax:delta], barb_increments=self.barb_increments, linewidth = .75, barbcolor = color, flagcolor = color)
def test_barb_limits(): ax = plt.axes() x = np.linspace(-5, 10, 20) y = np.linspace(-2, 4, 10) y, x = np.meshgrid(y, x) trans = mtransforms.Affine2D().translate(25, 32) + ax.transData plt.barbs(x, y, np.sin(x), np.cos(y), transform=trans) # The calculated bounds are approximately the bounds of the original data, # this is because the entire path is taken into account when updating the # datalim. assert_array_almost_equal(ax.dataLim.bounds, (20, 30, 15, 6), decimal=1)
def plot_vector_barbs(radar, r, u, v): azimuth = radar.azimuth['data'].reshape(10,360) rang = radar.range['data'] velocity_radial = radar.fields['velocity']['data'].reshape(10,360,253) theta, ran = np.meshgrid(azimuth[3,:], rang[r]) plt.figure() plt.subplot(111, polar=True) plt.barbs(theta, ran, u[3,:,r], v[3,:,r], velocity_radial[3,:,r]) plt.show() #plt.savefig('Radar_Qxb_Band_S - Barbs ({:.2f} km Range).png'.format((r*1490)/1000.), format='png') plt.close()
def plot_dewpoint_temperature(ncFile, targetDir, windScaleFactor=50): logger = PyPostTools.pyPostLogger() fig, ax, X, Y = prepare_plot_object(ncFile) st, fh, fh_int = getTimeObjects(ncFile) TD = ncFile["TD"] TD_F = Conversions.C_to_F(TD) clevs = np.linspace(-20, 85, 36) norm = matplotlib.colors.BoundaryNorm(clevs, 36) contours = plt.contourf(X, Y, TD_F, clevs, norm=norm, cmap=ColorMaps.td_colormap, transform=ccrs.PlateCarree()) cbar = plt.colorbar(ax=ax, orientation="horizontal", pad=.05) cbar.set_label("Dewpoint Temperature ($^\circ$ F)") u = ncFile["SFC_U"] v = ncFile["SFC_V"] uKT = Conversions.ms_to_kts(u) vKT = Conversions.ms_to_kts(v) plt.barbs(to_np(X[::windScaleFactor, ::windScaleFactor]), to_np(Y[::windScaleFactor, ::windScaleFactor]), to_np(uKT[::windScaleFactor, ::windScaleFactor]), to_np(vKT[::windScaleFactor, ::windScaleFactor]), transform=ccrs.PlateCarree(), length=6) plt.title("Surface Dewpoint Temperature ($^\circ$F), Winds (kts)") plt.text(0.02, -0.02, "Forecast Time: " + fh.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.text(0.7, -0.02, "Initialized: " + st.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.subplots_adjust(bottom=0.1) plt.savefig(targetDir + "/TD_F" + str(fh_int)) plt.close(fig) return True
def _windbarbs(nc, time, y, x, P, thin_locs, n=45.0, color="black"): uwind = 0.5 * (nc.variables["U"][time, :, y, x] + nc.variables["U"][time, :, y, x + 1]) vwind = 0.5 * (nc.variables["V"][time, :, y, x] + nc.variables["V"][time, :, y + 1, x]) zmax = len(uwind[thin_locs]) delta = 1 baraxis = [n for _j in range(0, zmax, delta)] plt.barbs( baraxis, P[thin_locs], uwind[thin_locs], vwind[thin_locs], barb_increments=barb_increments, linewidth=0.75, color=color, )
def plot_dwp(): print " DEWPOINT" # Set Figure Size (1000 x 800) plt.figure(figsize=(width, height), frameon=False) qhum = nc.variables['Q2'] # Convert Surface Pressure to Mean Sea Level Pressure stemps = temps[time] + 6.5 * nc.variables['HGT'][time] / 1000. mslp = psfc[time] * np.exp( 9.81 / (287.0 * stemps) * nc.variables['HGT'][time]) * 0.01 # Find saturation vapor pressure es = 6.112 * np.exp(17.67 * temps[time] / (temps[time] + 243.5)) w = qhum[time] / (1 - qhum[time]) e = (w * psfc[time] / (.622 + w)) / 100 Td_C = (243.5 * np.log(e / 6.112)) / (17.67 - np.log(e / 6.112)) Td_F = (Td_C * 9 / 5) + 32 DP_LEVS = range(-10, 85, 1) DP_CLEVS = range(40, 90, 10) # Contour and fill the dewpoint temperature Td = plt.contourf(x, y, Td_F, DP_LEVS, cmap=coltbls.dewpoint1(), extend='min') Td_lev = plt.contour(x, y, Td_F, DP_CLEVS, colors='k', linewidths=.5) plt.clabel(Td_lev, inline=1, fontsize=7, fmt='%1.0f', inline_spacing=1) # Contour the pressure # P=plt.contour(x,y,mslp,V=2,colors='k',linewidths=1.5) # plt.clabel(P,inline=1,fontsize=8,fmt='%1.0f',inline_spacing=1) #plt.clabel(T,inline=1,fontsize=10) # Convert winds from m/s to kts and then draw barbs u_wind_kts = u_wind_ms[time] * 1.94384449 v_wind_kts = v_wind_ms[time] * 1.94384449 plt.barbs(x_th,y_th,u_wind_kts[::thin,::thin],\ v_wind_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') title = 'Surface Dwp, 10m Wind (kts)' prodid = 'dewp' units = u"\u00B0" + "F" drawmap(Td, title, prodid, units)
def _make_barb(self, temperature, theta, speed, angle): """Add the barb to the plot at the specified location.""" u, v = self._uv(speed, angle) if 0 < speed < _BARB_BINS[0]: # Plot the missing barbless 1-2 knots line. length = self._kwargs['length'] pivot_points = dict(tip=0.0, middle=-length / 2.) pivot = self._kwargs.get('pivot', 'tip') offset = pivot_points[pivot] verts = [(0.0, offset), (0.0, length + offset)] rangle = math.radians(-angle) verts = mtransforms.Affine2D().rotate(rangle).transform(verts) codes = [Path.MOVETO, Path.LINETO] path = Path(verts, codes) size = length ** 2 / 4 xy = np.array([[temperature, theta]]) barb = PathCollection([path], (size,), offsets=xy, transOffset=self._transform, **self._custom_kwargs) barb.set_transform(mtransforms.IdentityTransform()) self.axes.add_collection(barb) else: barb = plt.barbs(temperature, theta, u, v, transform=self._transform, **self._kwargs) return barb
def wind_barb_spaced(ax, prof, xpos=1.0, yspace=0.04): # yspace = 0.04 means ~26 barbs. s = [] bot = 2000. # Space out wind barbs evenly on log axis. for ind, i in enumerate(prof.pres): if i < 100: break if np.log(bot / i) > yspace: s.append(ind) bot = i # x coordinate in (0-1); y coordinate in pressure log(p) b = plt.barbs(xpos * np.ones(len(prof.pres[s])), prof.pres[s], prof.u[s], prof.v[s], length=5.8, lw=0.35, clip_on=False, transform=ax.get_yaxis_transform()) # 'knots' label under wind barb stack kts = ax.text(1.0, prof.pres[0] + 10, 'knots', clip_on=False, transform=ax.get_yaxis_transform(), ha='center', va='top', size=7) return b, kts
def _make_barb(self, temperature, theta, speed, angle): """Add the barb to the plot at the specified location.""" u, v = self._uv(speed, angle) if 0 < speed < _BARB_BINS[0]: # Plot the missing barbless 1-2 knots line. length = self._kwargs['length'] pivot_points = dict(tip=0.0, middle=-length / 2.) pivot = self._kwargs.get('pivot', 'tip') offset = pivot_points[pivot] verts = [(0.0, offset), (0.0, length + offset)] rangle = math.radians(-angle) verts = mtransforms.Affine2D().rotate(rangle).transform(verts) codes = [Path.MOVETO, Path.LINETO] path = Path(verts, codes) size = length**2 / 4 xy = np.array([[temperature, theta]]) barb = PathCollection([path], (size, ), offsets=xy, transOffset=self._transform, **self._custom_kwargs) barb.set_transform(mtransforms.IdentityTransform()) self.axes.add_collection(barb) else: barb = plt.barbs(temperature, theta, u, v, transform=self._transform, **self._kwargs) return barb
def windbarbs(self, nc, time, y, x, P, thin_locs, n=45.0, color='black'): uwind = 0.5 * (nc.variables['U'][time, :, y, x] + nc.variables['U'][time, :, y, x + 1]) vwind = 0.5 * (nc.variables['V'][time, :, y, x] + nc.variables['V'][time, :, y + 1, x]) zmax = len(uwind[thin_locs]) delta = 1 baraxis = [n for _j in range(0, zmax, delta)] # pdb.set_trace() plt.barbs(baraxis, P[thin_locs], uwind[thin_locs], vwind[thin_locs], barb_increments=self.barb_increments, linewidth=.75, color=color)
def windbarbs_real(self, uwind, vwind, P, delta=3, color='red', n=37.5): # Is wind in kt or m/s? .... uwind* those = N.where(uwind == -9999) # Find nonsense values uwind = N.delete(uwind, those) vwind = N.delete(vwind, those) P = N.delete(P, those) zmax = len(uwind) # n is x-ax position on skewT for barbs. baraxis = [n for _j in range(0, zmax, delta)] plt.barbs(baraxis, P[0:zmax:delta], uwind[0:zmax:delta], vwind[0:zmax:delta], barb_increments=self.barb_increments, linewidth=.75, barbcolor=color, flagcolor=color)
def plot_500_vort(time,lon_min,lon_max,lat_min,lat_max,title_font_size,declutter = None): r""" This function plots relative vorticity, gepotential height, and wind (knots) on a grid. Parameters: ----------- time(int): Time index for the time being plotted lon_min,lon_max(float): Minimum and maximum longitude of the grid domain lat_min,lat_max(float): Minimum and maximum latitude of the grid domain title_font_size(float): Font size of the title and colorbar label declutter(int): Sets the declutter rate of the wind barbs; Greater number means lower barb density; Default is 12 """ if declutter is None: declutter = 12 title_name = '500 mb Relative Vorticity, Geopotential height (dam), Winds (kt) ' time = input('Enter the analysis time:') cmin = 0; cmax = 26; cint = 1; clevs = np.round(np.arange(cmin,cmax,cint),2) plt.figure(figsize=(10,10)) xlim = np.array([lon_min,lon_max]); ylim = np.array([lat_min,lat_max]) m = Basemap(projection='cyl',lon_0=np.mean(xlim),lat_0=np.mean(ylim),llcrnrlat=ylim[0],urcrnrlat=ylim[1],llcrnrlon=xlim[0],urcrnrlon=xlim[1],resolution='i') m.drawcoastlines(); m.drawstates(), m.drawcountries() cs = m.contourf(lon2,lat2,relative_vort[time,:,:].T,clevs,cmap='YlOrRd',extend='both') cs2 = m.contour(lon2,lat2,z[time,:,:].T, colors = 'k') plt.clabel(cs2, fontsize=10, inline=1,fmt = '%1.0f') plt.barbs(lon2[::declutter,::declutter],lat2[::declutter,::declutter],u[time,::declutter,::declutter].T,v[time,::declutter,::declutter].T) m.drawcounties() cbar = m.colorbar(cs,size='2%') cbar.ax.set_ylabel(r'[$10^{-5}$ $s^{-1}$]',size=title_font_size) plt.title(str(title_name) + str(time),name='Calibri',size=title_font_size) plot = plt.show(block=False) return plot
def plot_dwp(): print " DEWPOINT" # Set Figure Size (1000 x 800) plt.figure(figsize=(width,height),frameon=False) qhum = nc.variables['Q2'] # Convert Surface Pressure to Mean Sea Level Pressure stemps = temps[time]+6.5*nc.variables['HGT'][time]/1000. mslp = psfc[time]*np.exp(9.81/(287.0*stemps)*nc.variables['HGT'][time])*0.01 # Find saturation vapor pressure es = 6.112 * np.exp(17.67 * temps[time]/(temps[time] + 243.5)) w = qhum[time]/(1-qhum[time]) e = (w * psfc[time] / (.622 + w)) / 100 Td_C = (243.5 * np.log(e/6.112))/(17.67-np.log(e/6.112)) Td_F = (Td_C * 9 / 5) + 32 DP_LEVS = range(-10,85,1) DP_CLEVS = range(40,90,10) # Contour and fill the dewpoint temperature Td=plt.contourf(x,y,Td_F,DP_LEVS,cmap=coltbls.dewpoint1(),extend='min') Td_lev = plt.contour(x,y,Td_F,DP_CLEVS,colors='k',linewidths=.5) plt.clabel(Td_lev,inline=1,fontsize=7,fmt='%1.0f',inline_spacing=1) # Contour the pressure # P=plt.contour(x,y,mslp,V=2,colors='k',linewidths=1.5) # plt.clabel(P,inline=1,fontsize=8,fmt='%1.0f',inline_spacing=1) #plt.clabel(T,inline=1,fontsize=10) # Convert winds from m/s to kts and then draw barbs u_wind_kts = u_wind_ms[time] * 1.94384449 v_wind_kts = v_wind_ms[time] * 1.94384449 plt.barbs(x_th,y_th,u_wind_kts[::thin,::thin],\ v_wind_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') title = 'Surface Dwp, 10m Wind (kts)' prodid = 'dewp' units = u"\u00B0" + "F" drawmap(Td, title, prodid, units)
def plot_thte(): """Plot surface theta-e map""" print " THETA-E" plt.figure(figsize=(width,height),frameon=False) qhum = nc.variables['Q2'] thte = (temps[time] + qhum[time] * 2500000.0/1004.0) * (100000/psfc[time]) ** (287.0/1004.0) THTE_LEVS = range(270,360,5) THTE = plt.contourf(x,y,thte,THTE_LEVS,cmap=coltbls.thetae(),extend='max') u_wind_kts = u_wind_ms[time] * 1.94384449 v_wind_kts = v_wind_ms[time] * 1.94384449 plt.barbs(x_th,y_th,u_wind_kts[::thin,::thin],\ v_wind_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') title = 'Theta-e, 10 m Wind (kt)' prodid = 'thte' units = 'K' drawmap(THTE, title, prodid, units)
def main(): fname = '/Users/hhuang/Downloads/gfsanl_4_20160628_0000_000.nc' # fname = '/Users/hhuang/Downloads/fnl_20160628_00_00.grib2.nc' axis_lim = [80., 130., 15., 50.] level = 500. time_str, lon, lat, t_var, hgt_var, u_var, v_var = read_gfs_data( fname, level=level, axis_lim=axis_lim) t_min, t_max, t_step = -20., 8., 2. t_level = np.linspace(t_min, t_max, (t_max - t_min) / t_step + 1) h_min, h_max, h_step = 560, 592., 4 h_level = np.linspace(h_min, h_max, (h_max - h_min) / h_step + 1) plt.figure(figsize=(10, 8)) plt.title('%g' % level + ' hPa Synoptic Analysis with GSF Analysis Data\nUTC' + time_str) cf = plt.contourf(lon, lat, t_var, vmin=t_min, vmax=t_max, cmap=cmaps.WhiteBlueGreenYellowRed, levels=t_level) cb = plt.colorbar(cf, ax=plt.gca(), ticks=t_level) cb.set_label('$\mathrm{Temperature(^\circ C)}$') cs = plt.contour(lon, lat, hgt_var, colors='b', levels=h_level) plt.clabel(cs, cs.levels, fmt='%g', fontsize=6, inline_spacing=10) plt.barbs(lon[::5, ::5], lat[::5, ::5], u_var[::5, ::5], v_var[::5, ::5], length=5) plt.axis(axis_lim) plt.xlabel('$\mathrm{Longitude(^\circ E)}$') plt.ylabel('$\mathrm{Lattitude(^\circ N)}$') plt.show()
def plot_surface(): print(" SURFACE") # Set Figure Size (1000 x 800) plt.figure(figsize=(width,height),frameon=False) # Convert Surface Pressure to Mean Sea Level Pressure stemps = temps[time]+6.5*nc.variables['HGT'][time]/1000. mslp = nc.variables['PSFC'][time]*np.exp(9.81/(287.0*stemps)*nc.variables['HGT'][time])*0.01 + (6.7 * nc.variables['HGT'][time] / 1000) # Convert Celsius Temps to Fahrenheit ftemps = (9./5.)*(temps[time]-273) + 32 T_LEVS = range(-10,125,5) # Contour and fill the temperature T=plt.contourf(x,y,ftemps,T_LEVS,cmap=coltbls.sftemp()) # Contour the pressure P=plt.contour(x,y,mslp,V=2,colors='k',linewidths=1.5) plt.clabel(P,inline=1,fontsize=8,fmt='%1.0f',inline_spacing=1) #plt.clabel(T,inline=1,fontsize=10) # Convert winds from m/s to kts and then draw barbs u_wind_kts = u_wind_ms[time] * 1.94384449 v_wind_kts = v_wind_ms[time] * 1.94384449 plt.barbs(x_th,y_th,u_wind_kts[::thin,::thin],\ v_wind_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') title = 'Sfc Temp, MSLP (mb), 10m Wind (kts)' prodid = 'pmsl' units = u"\u00B0" + "F" drawmap(T, title, prodid, units)
def plot_surface(): print(" SURFACE") # Set Figure Size (1000 x 800) plt.figure(figsize=(width, height), frameon=False) # Convert Surface Pressure to Mean Sea Level Pressure stemps = temps[time] + 6.5 * nc.variables['HGT'][time] / 1000. mslp = nc.variables['PSFC'][time] * np.exp( 9.81 / (287.0 * stemps) * nc.variables['HGT'][time]) * 0.01 + ( 6.7 * nc.variables['HGT'][time] / 1000) # Convert Celsius Temps to Fahrenheit ftemps = (9. / 5.) * (temps[time] - 273) + 32 T_LEVS = range(-10, 125, 5) # Contour and fill the temperature T = plt.contourf(x, y, ftemps, T_LEVS, cmap=coltbls.sftemp()) # Contour the pressure P = plt.contour(x, y, mslp, V=2, colors='k', linewidths=1.5) plt.clabel(P, inline=1, fontsize=8, fmt='%1.0f', inline_spacing=1) #plt.clabel(T,inline=1,fontsize=10) # Convert winds from m/s to kts and then draw barbs u_wind_kts = u_wind_ms[time] * 1.94384449 v_wind_kts = v_wind_ms[time] * 1.94384449 plt.barbs(x_th,y_th,u_wind_kts[::thin,::thin],\ v_wind_kts[::thin,::thin], length=5,\ sizes={'spacing':0.2},pivot='middle') title = 'Sfc Temp, MSLP (mb), 10m Wind (kts)' prodid = 'pmsl' units = u"\u00B0" + "F" drawmap(T, title, prodid, units)
data_to_plot=[] count=0 while count<record: if data[count,1]<=120 and data[count,0]<=33 and data[count,1]>=118 and data[count,0]>=31: data_to_plot=data_to_plot+[data[count,1],data[count,0],data[count,3],data[count,4]] count+=1 data_to_plot=np.asarray(data_to_plot).reshape([len(data_to_plot)/4,4]) radar_loc={"lon":118.69,"lat":32.19} radar_file_path="/media/qzhang/240E5CF90E5CC608/2011_07_18/radar/Z_RADR_I_Z9250_20110718110000_O_DOR_SA_CAP.bin" y,fw,j,fs=radar_read(radar_file_path) nx,ny,nz=sph2cart(y,fw,j) """ ax=plt.subplot(1,1,1) ax.barbs(data[:,1],data[:,0],data[:,3],data[:,4]) plt.show() """ plt.subplot(1,1,1) plt.pcolor(ny,nx,fs,cmap='gist_ncar',vmin=10,vmax=75) plt.axis([-80,160,-140,100]) plt.colorbar(ticks=np.linspace(10,75,14)) plt.subplot(1,1,1) plt.barbs((data_to_plot[:,0]-radar_loc["lon"])*110,(data_to_plot[:,1]-radar_loc["lat"])*110,data_to_plot[:,2],data_to_plot[:,3]) plt.title("2011-07-18_11:00 UTC",fontsize=20) plt.xlabel("Longitude",fontsize=14) plt.ylabel("Latitude",fontsize=14) plt.xticks([-80,-20,40,100,160],[118.0,118.5,119.0,119.5,120.0]) plt.yticks([-140,-80,-20,40,100],[31.0,31.5,32,32.5,33]) plt.show()
def plotbarbs(u, v, z, everyW): for i in np.arange(0, len(u), everyW): if z[i] < 16: pl.barbs(xbarbs, z[i] * 1000, u[i] / knms, v[i] / knms)
# PLOT CONTOURS FOR WIND SPEEDS cs2 = pyplot.contour(xvals, z, u-20, levels=[0,5,10,20], colors=['0.5', '0.3', '0.1'], linewidths='2') # PLOT MOMENTUM TENDENCIES cs3 = pyplot.contourf(xvals, z, f, levels=np.arange(-120,-10,20), cmap=pyplot.get_cmap('Blues_r'), alpha=0.6) cs5 = pyplot.contourf(xvals, z, f, levels=np.arange(20,300,30), cmap=pyplot.get_cmap('Reds'), alpha=0.6) # PLOT MICROPHYSICS TENDENCIES #cs3 = pyplot.contourf(xvals, z, prevp, levels=np.arange(-25,0,4), cmap=pyplot.get_cmap('Blues_r'), extend='min', alpha=0.6) #cs3 = pyplot.contourf(xvals, z, psdep, levels=np.arange(-25,0,4), cmap=pyplot.get_cmap('Blues_r'), extend='min', alpha=0.6) #cs3 = pyplot.contourf(xvals, z, pgmlt, levels=np.arange(-200,0,25), cmap=pyplot.get_cmap('Blues_r'), extend='min', alpha=0.6) #cs3 = pyplot.contourf(xvals, z, psmlt, cmap=pyplot.get_cmap('Blues_r'), alpha=0.6) #pyplot.contour(xvals, z, prevp, levels=[-1], color='blue', alpha=0.6, linewidths=0.5) #pyplot.contour(xvals, z, psdep, levels=[-1], color='blue', linestyles='dotted') # PLOT VERTICAL MOTION >= 1,-1 #cs2 = contourf(xvals, z, wmcross/1.94, levels=[1,100], colors='red', alpha=0.2) #cs2 = contourf(xvals, z, wmcross/1.94, levels=[-1,-100], colors='blue', alpha=0.2) # PLOT WIND BARBS IN PLANE OF CROSS-SECTION pyplot.barbs(xvals[::skipx], z[::skipz], u[::skipz,::skipx]-20, w[::skipz,::skipx], length=6, barbcolor='0.4', lw=0.5, sizes=dict(emptybarb=0.05)) #cs = pyplot.contourf(np.arange(0,297), z, TENDxmax, axis=0, alpha=0.7) #pyplot.clabel(cs2, fontsize=9, inline=1, fmt='%1.0f') pyplot.ylim((0,12)) pyplot.xlim((20,60)) pyplot.colorbar(cs5, orientation='horizontal') pyplot.savefig('tend.png', bbox_inches='tight')
def makePlot(self, ax, fix_lon_pos=True): """Help on built-in function makePlot in module GeoPlot: makePlot(...) makePlot(ax,[, fix_lon_pos,]) This function handles the majority of the file IO, and plotting including: a) Reading in the NetCDF file, choosing the approrite vertical level and time step as defined in GeoPlot namelist_dictionary. b) Making any required unit conversions for temperature, and merging U/V wind components into speed c) Contour filling and plotting and geographic overlay d) Any automatic titling or colorbars Parameters ---------- ax : matplotlib subplot, a defined matplotlib subplot object with a cartopy projection. fix_lon_pos : Boolean (optional), A flag that will adjust longitude to run from 0-360 instead of -180 to 180 useful for domains that straddle the date line. Notes ---------- Assumes data is in NetCDF format Assumes that the latitude / longitude variables are in decimal degrees and that the NetCDF variable names are set to the GeoPlot attributes: latName and lonName. Assumes that the time coordinate information is stored in the "Time" variable within the NetCDF file. If the "Time" variable has the attribute "calendar" the time coordinate information will be determined using num2date, otherwise it will use datetime. All time information is converted to datetime. Can convert the units of temperature only, if the namelist variable "convert_temp" is set to "C" or "F" Accumulated precpitation variables are accumuated over the time-period specified by the namelist_dictionary['pcp_accum_times'] variable. Mean Sea Level Pressure is special and largly ignores namelist contour attributes. Returns ------- nothing, but it adds data to a pre-existing subplot, which can be displayed or saved to an image file Example Usage ------------- Gplot=GeoPlot() .... Gplot=define_projection() ax=plt.subplot(111,projection=Gplot.projection) Gplot.makePlot(ax) plt.show() .... """ from netCDF4 import Dataset, num2date from datetime import datetime, timedelta self.CheckNamelist() title = '' show_hls = True var_range = self.namelist_dictionary['var_range'] if type(self.namelist_dictionary['pfx']) == str: ##critical check, if the namelist prefix is a string, then make it a list ##so it behaves correctly in the below loop. self.namelist_dictionary['pfx'] = [self.namelist_dictionary['pfx']] for pdx, p in enumerate(self.namelist_dictionary['pfx']): c_count = 1 w_count = 0 wskp = int(self.namelist_dictionary['barb_skip']) barb_kwargs = self.namelist_dictionary['wind_kwargs'][0] if pdx == 1: print("Resetting a couple of things to avoid overlap...") self.namelist_dictionary['colorbar'] = False show_hls = False filepath = '%s/*%s*.nc' % (self.namelist_dictionary['data_path'], p) ## Check if file exists. try: datafile = glob.glob(filepath)[0] print("Opening %s" % datafile) except: self.print_fatal("NO Files with path %s found.... exiting." % filepath) ## Open NETCDF file and get times, lat/lon ncdata = Dataset(datafile, 'r') ## open for appending, ## DO NOT NEED TO DO THE DESCRIPTION STUFF! or dimenion setting! ## ## CHECK IF WRF FILE! ## wrf_special = [] if 'TITLE' in ncdata.ncattrs() and 'WRF' in ncdata.TITLE: pcp_varnames = [ 'Gridscale Precipitation rate', 'Gridscale Snowfall rate' ] if all(item in ncdata.variables for item in pcp_varnames) == True: wrf_special = wrf_special + [ 'WRF Accumulated Precipitation', 'WRF Accumulated Snow' ] if 'Convective Precipitation rate' in ncdata.variables: ## Set flag to include convective precip in wrf accumulated precip variable ## Doesn't matter if cumulus parameterization is off in model. wrf_convective_pcp = True else: wrf_convective_pcp = False try: times = num2date(ncdata.variables['Time'][:], units=ncdata.variables['Time'].units, calendar=ncdata.variables['Time'].calendar) times = [ datetime.strptime( datetime.strftime(i, '%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S') for i in times ] except: times = [ datetime.strptime(ncdata.variables['Time'].units, ncdata.variables['Time'].units) + timedelta(hours=float(ss)) for ss in ncdata.variables['Time'][:] ] time_choice_strp = datetime.strptime( self.namelist_dictionary['time_step'], self.namelist_dictionary['time_format']) time_indx = np.argmin(np.abs(np.array(times) - time_choice_strp)) try: levels = ncdata.variables['Levels'][:].squeeze() except: print( 'WARNING, I CANNOT FIND THE VARIABLE "LEVELS" in the netcdf FILE' ) print( "Assuming this file doesn't have any levels, assuming this is a surface file." ) print("Setting dummy array to levels=[1000]") levels = np.array([1000]) lons, lats = ncdata.variables[self.lonName][:].squeeze( ), ncdata.variables[self.latName][:].squeeze() if fix_lon_pos == True: lons = np.ma.masked_less(lons, 0.0).filled(360. + lons) lev_idx = [] for vv in self.namelist_dictionary['levels']: if vv not in levels: self.print_warning([ "Variable levels is not in dataset", "Defaulting to nearest vertical level." ]) lev_idx.append(np.argmin(np.abs(levels - vv))) ##Build list of avaiable variables from netCDF file. skp_list = ['Time', self.lonName, self.latName, 'Levels'] special = ['Wind speed', '10m Wind speed', 'NARR_pcp' ] + self.stg4_special + wrf_special var_list = [] for vdx, v in enumerate(ncdata.variables): if vdx == 0 and self.namelist_dictionary['print_vars'] == True: print("--------------------------") print("Printing avaialble variables") print("--------------------------") if v not in skp_list: if self.namelist_dictionary['print_vars'] == True: print(" -- %s [%s] | %s" % (v, ncdata.variables[v].units, ncdata.variables[v].longname)) var_list.append(v) if self.namelist_dictionary['print_vars'] == True: print("--------------------------") if self.namelist_dictionary['print_vars'] == True: print("--------------------------") print("Printing avaiable special variables") print("--------------------------") for v in special: print(" -- %s " % (v)) pc.AddMap(ax, extent=self.namelist_dictionary['geo_box'], features=self.namelist_dictionary['features'], reso=self.namelist_dictionary['map_resolution']) ## initialize Z order if self.namelist_dictionary['over_land'] == True: zorder = 3 else: zorder = 2 for vdx, vari in enumerate(self.namelist_dictionary['vars']): print("---------------------------") print("Working on Variable %s" % vari) print("---------------------------") if self.namelist_dictionary['plot_winds'][vdx] == True: if vari == '10m Wind speed': UU = ncdata.variables['10 metre U wind component'][ time_indx, :] VV = ncdata.variables['10 metre V wind component'][ time_indx, :] else: print("Collecting Wind data for level %i hPa" % self.namelist_dictionary['levels'][vdx]) if self.namelist_dictionary['levels'][vdx] == 1000: print( "Assuming winds at 1000 hPa are 10m winds....") UU = ncdata.variables[self.U10][time_indx, :] VV = ncdata.variables[self.V10][time_indx, :] else: UU = ncdata.variables[self.U][time_indx, lev_idx[vdx], :] VV = ncdata.variables[self.V][time_indx, lev_idx[vdx], :] if vari not in var_list and vari not in special: print( "Your Variable is not in the list! Defaulting to 2M Temperature" ) vari = '2 metre temperature' # THIS NEXT SOMEWHAT UNWIELDY LOOKING BLOCK OF CODE ACTS TO PLOT "Special Variables" # that can't just be pulled directly from the netCDF file. # this includes catches for both observational precipitation from (stage 4 data set) # and NARR precpitation. # Special variables: # - Wind Speed # - 10m Wind Speed # - stg4_pcp # - NARR_pcp # - WRF_pcp if vari == 'Wind speed': # Special case here, if we want to plot windspeed, but we have already loaded # u and v wind components at this level from first step, don't take the time and effort # to reload them just for the sake of slightly cleaner code. if self.namelist_dictionary['plot_winds'] == True: ##Don't reload the data if we don't have to... var_data = np.sqrt(UU**2. + VV**2.) else: ## otherwise, you gotta load the data. var_data=np.sqrt(ncdata.variables[self.U][time_indx,lev_idx[vdx],:]**2.+ \ ncdata.variables[self.V][time_indx,lev_idx[vdx],:]**2.) units = 'm s^-1' if vdx == 0: title = '%i hPa Wind Speed' % self.namelist_dictionary[ 'levels'][vdx] else: title += '\n %i hPa Wind Speed' % self.namelist_dictionary[ 'levels'][vdx] elif vari == '10m Wind speed': var_data=np.sqrt(ncdata.variables[self.U10][time_indx,:]**2.+ \ ncdata.variables[self.V10][time_indx,:]**2.) units = 'm s^-1' if vdx == 0: title = '10m Wind Speed' else: title += '\n 10m Wind Speed' ## SPECIAL BLOCK OF SPECIAL VALUES -- > PRECIPITATION elif vari == 'stg4_pcp': ## "Observed" Stage 4 precip lons,lats,var_data,title,units=\ pc.acc_precip(self.namelist_dictionary,vdx=vdx,src_name='Stage 4',title=title) elif vari == 'NARR_pcp': # "Observed" NARR Precip lons,lats,var_data,title,units=\ pc.acc_precip(self.namelist_dictionary,vdx=0,src_name='NARR',title=title) elif vari == 'WRF Accumulated Precipitation': ## WRF total Precipitation var_data, title, units = pc.wrf_acc_pcp( self.namelist_dictionary, times, time_indx, ncdata, vdx=vdx, title=title) elif vari == 'WRF Accumulated Snow': var_data, title, units = pc.wrf_acc_snow( self.namelist_dictionary, times, time_indx, ncdata, vdx=vdx, title=title) else: units = ncdata.variables[vari].units ## NOT USING A SPECIAL VARIABLE! ### lons, lats = ncdata.variables['Longitude'][:].squeeze( ), ncdata.variables['Latitude'][:].squeeze() ## IF NOT A SPECIAL VARIABLE !!# if 'z' not in ncdata.variables[vari].dimensions: #This is a single level (surface) variable, don't use L_index! if np.ndim( ncdata.variables[vari][:] ) < 3: ## THEN THIS IS A Time-Invarient Variable! var_data = ncdata.variables[vari][:] else: var_data = ncdata.variables[vari][time_indx, :] else: #otherwise, use the level index. if np.ndim( ncdata.variables[vari][:] ) < 4: ## THEN THIS IS A Time-Invarient Variable! var_data = ncdata.variables[vari][lev_idx[vdx], :] else: var_data = ncdata.variables[vari][time_indx, lev_idx[vdx], :] #print(np.shape(var_data),np.nanmax(var_data),np.nanmin(var_data)) ## SPECIAL CASE --> CONVERT TEMPERATURE! if 'temperature' in vari.lower(): if self.namelist_dictionary['convert_temp'][ vdx] == 'F': print("Converting Temperature to F") var_data = pc.KtoF(var_data) units = 'F' elif self.namelist_dictionary['convert_temp'][ vdx] == 'C': print("Converting Temperature to C") var_data = pc.KtoC(var_data) units = 'C' if vari != 'Mean sea level pressure': if vdx == 0: title = ncdata.variables[ vari].longname + ' [%s]' % units else: title = '\n %s' % ncdata.variables[ vari].longname + ' [%s]' % units units = ncdata.variables[vari].units if self.namelist_dictionary['smooth_field'][vdx] > 0: print("Smoothing data field with sigma of %i" % self.namelist_dictionary['smooth_field'][vdx]) var_data = pc.smooth_field( var_data, self.namelist_dictionary['smooth_field'][vdx]) if self.namelist_dictionary[ 'mslp_hilo'] == True and vari == 'Mean sea level pressure' and pdx == 0: print("Special Plot: MSLP with hi's and lo's") mslp_title = pc.plot_mslp(ax, lons, lats, var_data / 100., times[time_indx], hsize=50 * wskp / 1.8, lsize=25 * wskp / 1.8, zorder=6, hl=show_hls) units = 'hPa' if vdx == 0: title = ncdata.variables[ vari].longname + ' [%s]' % units else: title += '\n %s' % ncdata.variables[ vari].longname + ' [%s]' % units else: if vdx == 0 and self.namelist_dictionary[ 'shade_first'] == True: ## SHADE FIRST VARIABLE! ## title += ' (shaded)' if self.namelist_dictionary['linspace'][vdx] == True: clevels = np.linspace(var_range[vdx][0], var_range[vdx][1], var_range[vdx][2]) else: clevels = np.arange(var_range[vdx][0], var_range[vdx][1], var_range[vdx][2]) if self.namelist_dictionary[ 'shade_type'] == 'contourf': self.im = plt.contourf( lons, lats, var_data, cmap=self.namelist_dictionary['colormap'], zorder=zorder, levels=clevels, transform=ccrs.PlateCarree(), extend=self.namelist_dictionary['extend']) else: self.im = plt.pcolormesh( lons, lats, np.ma.masked_less(var_data, var_range[vdx][0]), cmap=self.namelist_dictionary['colormap'], zorder=zorder, vmin=var_range[vdx][0], vmax=var_range[vdx][1], transform=ccrs.PlateCarree()) if self.namelist_dictionary['colorbar'] == True: cbar = plt.colorbar(self.im, fraction=0.046, pad=0.04) cbar.set_label('[%s]' % units, fontsize=12.) else: if pdx == 0: if self.namelist_dictionary['linspace'][ vdx] == True: clevels = np.linspace(var_range[vdx][0], var_range[vdx][1], var_range[vdx][2]) else: clevels = np.arange(var_range[vdx][0], var_range[vdx][1], var_range[vdx][2]) contour_kwargs = self.namelist_dictionary[ 'contour_kwargs%i' % c_count][0] print(contour_kwargs) C = plt.contour(lons, lats, var_data, zorder=zorder, levels=clevels, transform=ccrs.PlateCarree(), **contour_kwargs) c_count = c_count + 1 ## Move on to next variable --> ONLY IF ENOUGH ARGUMENTS! ## if self.namelist_dictionary['clabels'][ vdx] == True: clabels = plt.clabel( C, fmt=self.namelist_dictionary['clabfmt'] [vdx]) if self.namelist_dictionary['clabbox'][ vdx] == True: for t in clabels: t.set_bbox({ 'facecolor': 'white', 'pad': 4 }) t.set_fontweight('heavy') title += ' (contoured)' if self.namelist_dictionary['plot_winds'][ vdx] == True and pdx == 0: lons, lats = ncdata.variables[self.lonName][:].squeeze( ), ncdata.variables[self.latName][:].squeeze() if self.namelist_dictionary['vector_type'] == 'barb': plt.barbs(lons[::wskp, ::wskp], lats[::wskp, ::wskp], UU[::wskp, ::wskp], VV[::wskp, ::wskp], transform=ccrs.PlateCarree(), zorder=zorder + 1, **barb_kwargs) elif self.namelist_dictionary[ 'vector_type'] == 'quiver': plt.quiver(lons[::wskp, ::wskp], lats[::wskp, ::wskp], UU[::wskp, ::wskp], VV[::wskp, ::wskp], transform=ccrs.PlateCarree(), zorder=zorder + 1, **barb_kwargs) else: plt.streamplot(lons, lats, UU, VV, transform=ccrs.PlateCarree(), zorder=zorder + 1, **barb_kwargs) zorder = zorder + 1 self.current_title = title if self.namelist_dictionary['show_title'] == True: plt.title(title, loc='left', fontweight='bold') if self.namelist_dictionary['valid_title'] == True: plt.title('VALID: %s' % times[time_indx].strftime('%c'), loc='right')
def plot_wind_barbs(axes, z, p, u, v): for i in np.arange(0, len(z)): if (p[i] > pt_plot): plt.barbs(0, p[i], u[i], v[i], length=5, linewidth=.5)
def plot_wind(axes, z, p, u, v, x=0): for i in np.arange(0, len(z), 1): if (p[i] > pt_plot): plt.barbs(x, p[i], u[i], v[i], length=5, linewidth=.5)
import matplotlib.pyplot as plt import numpy as np x = np.linspace(-20, 20, 8) y = np.linspace( 0, 20, 8) # make 2D coordinates X, Y = np.meshgrid(x, y) U, V = X + 25, Y - 35 # plot the barbs plt.subplot(1,2,1) plt.barbs(X, Y, U, V, flagcolor='green', alpha=0.75) plt.grid(True, color='gray') # compare that with quiver / arrows plt.subplot(1,2,2) plt.quiver(X, Y, U, V, facecolor='red', alpha=0.75) # misc settings plt.grid(True, color='grey') plt.show()
def __init__(self, x, y, lat, rm, vm, b, dp, pe, rho, Ut): f = 2 * 7.292e-5 * np.sin(lat * np.pi / 180.0) # Coriolis parameter thetaFm = 0 tx = 1.0 * x # to create a new copy of x, not a pointer to x np.putmask(tx, x == 0, 1e-30) # to avoid divide by zero errors lam = np.arctan2(y, tx) r = np.sqrt(x**2 + y**2) np.putmask(r, r == 0, 1e-30) # to avoid divide by zero errors xkm = x * 1e-3 ykm = y * 1e-3 xx = xkm[0, ] yy = ykm[:, 0] cx = rm * 1e-3 * np.sin(np.arange(0, 6.29, 0.01)) # Circle for rmw plots. cy = rm * 1e-3 * np.cos(np.arange(0, 6.29, 0.01)) # Define parametric gradient wind (V) and vorticity (Z) profiles # using Holland (1980) bogus with core modified to quadratic. rmrb = (rm / r)**b rmrbs = rmrb.shape emrmrb = np.zeros(rmrbs, float) for i in range(rmrbs[0]): # needed to cope with Python OverflowError for j in range(rmrbs[1]): try: emrmrb[i, j] = np.exp(-rmrb[i, j]) except OverflowError: pass V = np.sqrt((b * dp / rho) * emrmrb * rmrb + (0.5 * f * r)**2) - 0.5 * abs(f) * r if dp < 4000.: Umod = Ut * (1. - (4000. - dp) / 4000.) else: Umod = Ut if (np.abs(V).max() / np.abs(Ut) < 5): Umod = Umod * (1. - (5. - np.abs(V).max() / np.abs(Ut)) / 5.) else: Umod = Umod fig, axes = plt.subplots(2, 2, subplot_kw={'aspect': 'equal'}, figsize=(18, 18)) ax = axes.flatten() #ax[0].hold(True) ax[0].set_xlim([-50, 50]) ax[0].set_ylim([-50, 50]) levels = np.arange(-20, 21, 2) cm = ax[0].contourf(xkm, ykm, V, np.arange(-100., 101, 5)) cs = ax[0].contour(xkm, ykm, V, np.arange(-100, 101, 5), colors='k') ax[0].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[0]) ax[0].plot(cx, cy, 'w') ax[0].plot(2 * cx, 2 * cy, 'w') Vt = np.ones(rmrbs, float) * Umod core = np.where(r >= 2. * rm) #Vt[core] = Umod*np.exp(-((r[core]/(2.*rm)) - 1.)**2.) Z = abs(f) + (b**2*dp*(rmrb**2)*emrmrb/(2*rho*r) -\ b**2*dp*rmrb*emrmrb/(2*rho*r) + r*f**2/4) \ / np.sqrt(b*dp*rmrb*emrmrb/rho + (r*f/2)**2) + \ (np.sqrt(b*dp*rmrb*emrmrb/rho + (r*f/2)**2))/r #ax[1].hold(True) ax[1].set_xlim([-50, 50]) ax[1].set_ylim([-50, 50]) levels = np.arange(-0.02, 0.021, .002) cm = ax[1].contourf(xkm, ykm, Z, np.arange(-0.02, 0.021, .002)) cs = ax[1].contour(xkm, ykm, Z, np.arange(-0.02, 0.021, .002), colors='k') ax[1].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[1]) ax[1].plot(cx, cy, 'w') if 0: # Quadratic core (NB."if" part of tree not yet Python-ised) Vm = V.max() rs = r[np.where(V == Vm)] rs = rs[0] rmrsb = (rm / rs)**b Vs = np.sqrt(b * dp / rho * np.exp(-rmrsb) * rmrsb + (0.5 * f * rs)**2) -0.5 * abs(f) * rs icore = np.where(r < rs) V[icore] = Vs * (r[icore] / rs) * (2 - (r[icore] / rs)) Z[icore] = Vs / rs * (4 - 3 * r[icore] / rs) else: # Fit cubic at rm, matching derivatives E = np.exp(1) Vm = (np.sqrt(b * dp / (rho * E) + (0.5 * f * rm)**2) - 0.5 * abs(f) * rm) dVm = (-np.abs(f)/2 + (E*(f**2)*rm*np.sqrt((4*b*dp/rho)/E + \ (f*rm)**2))/ \ (2*(4*b*dp/rho + E*(f*rm)**2))) d2Vm = (b*dp*(-4*b**3*dp/rho - (-2 + b**2)*E*(f*rm)**2)) / \ (E*rho*np.sqrt((4*b*dp)/(E*rho) + (f*rm)**2) * \ (4*b*dp*rm**2/rho + E*(f*rm**2)**2)) aa = (d2Vm / 2 - (dVm - Vm / rm) / rm) / rm bb = (d2Vm - 6 * aa * rm) / 2 cc = dVm - 3 * aa * rm**2 - 2 * bb * rm icore = np.nonzero(np.ravel(r < rm)) for ind in icore: V.flat[ind] = r.flat[ind] * \ (r.flat[ind] * (r.flat[ind]*aa + bb) + cc) Z.flat[ind] = r.flat[ind] * (r.flat[ind] * 4 * aa + 3 * bb) + 2 * cc pm = pe - dp * (1 - np.exp(-1)) V = V * np.sign(f) Z = Z * np.sign(f) #ax[2].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[2].set_xlim([-50, 50]) ax[2].set_ylim([-50, 50]) levels = np.arange(-20, 21, 2) cm = ax[2].contourf(xkm, ykm, V, np.arange(-100., 101, 5)) cs = ax[2].contour(xkm, ykm, V, np.arange(-100., 101, 5), colors='k') ax[2].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[2]) ax[2].plot(cx, cy, 'w') #ax[3].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[3].set_xlim([-50, 50]) ax[3].set_ylim([-50, 50]) levels = np.arange(-0.02, 0.021, .002) cm = ax[3].contourf(xkm, ykm, Z, np.arange(-0.02, 0.021, .002)) cs = ax[3].contour(xkm, ykm, Z, np.arange(-0.02, 0.021, .002), colors='k') ax[3].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[3]) ax[3].plot(cx, cy, 'w') fig.tight_layout() plt.savefig('radial_wind_vorticity.png') Vx = -V * y / r # Cartesian winds (??? divide by y ???) Vy = V * x / r I2 = (f + 2 * V / r) * (f + Z) # Inertial stability squared K = 50 # Diffusivity C = 0.002 # Drag coefficient # Calculate alpha, beta, gamma, chi, eta and psi in Kepert (2001). # The III's are to get the solution in the case where V/r > I. al = (f + (2 * V / r)) / (2 * K) be = (f + Z) / (2 * K) gam = V / (2 * K * r) III = np.nonzero(gam > np.sqrt(al * be)) # fixup = nonzero(ravel(isNaN(al) | isnan(be) | isnan(gam))) chi = np.abs((C / K) * V / np.sqrt(np.sqrt(al * be))) # chi[fixup] = np.nan eta = np.abs((C / K) * V / np.sqrt(np.sqrt(al * be) + np.abs(gam))) # eta[fixup] = np.nan psi = np.abs( (C / K) * V / np.sqrt(np.abs(np.sqrt(al * be) - np.abs(gam)))) # psi[fixup] = nan albe = np.sqrt(al / be) # Calculate A_k's ... p and m refer to k = +1 and -1. i = cmath.sqrt(-1) A0 = -chi * V * (1 + i * (1 + chi)) / (2 * chi**2 + 3 * chi + 2) # A0[fixup] = np.nan u0s = np.sign(f) * albe * A0.real # Symmetric surface wind component v0s = A0.imag Am = -(psi * (1 + 2 * albe + (1 + i) * (1 + albe) * eta) * Umod) \ / (albe * ((2 + 2 * i) * (1 + eta * psi) + 3 * psi + 3* i * eta)) AmIII = -(psi * (1 + 2 * albe + (1 + i) * (1 + albe) * eta) * Umod) \ / (albe * ((2 - 2 * i + 3 * (eta + psi) + (2 + 2 * i)*eta*psi))) Am[III] = AmIII[III] # First asymmetric surface component ums = albe * (Am * np.exp(-i * (thetaFm - lam) * np.sign(f))).real vms = np.sign(f) * (Am * np.exp(-i * (thetaFm - lam) * np.sign(f))).imag Ap = -(eta * (1 - 2 * albe + (1 + i)*(1 - albe) * psi) * Umod) \ / (albe * ((2 + 2*i)*(1 + eta * psi) + 3*eta + 3*i*psi)) ApIII = -(eta * (1 - 2 * albe + (1 - i)*(1 - albe)*psi)*Umod) \ / (albe * (2 + 2 * i + 3 * (eta + psi) + (2 -2 * i)*eta*psi)) Ap[III] = ApIII[III] # Second asymmetric surface component ups = albe * (Ap * np.exp(i * (thetaFm - lam) * np.sign(f))).real vps = np.sign(f) * (Ap * np.exp(i * (thetaFm - lam) * np.sign(f))).imag fig, axes = plt.subplots(2, 2, figsize=(18, 18), subplot_kw={'aspect': 'equal'}) ax = axes.flatten() #ax[0].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[0].set_xlim([-100, 100]) ax[0].set_ylim([-100, 100]) levels = np.arange(-20, 21, 2) cm = ax[0].contourf(xkm, ykm, u0s, np.arange(-50, 51, 5)) cs = ax[0].contour(xkm, ykm, u0s, np.arange(-50, 51, 5), colors='k') ax[0].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[0]) ax[0].plot(cx, cy, 'w') ax[0].plot(2 * cx, 2 * cy, 'w') ax[0].set_xlabel("u0s") #ax[1].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[1].set_xlim([-100, 100]) ax[1].set_ylim([-100, 100]) levels = np.arange(-20, 21, 2) cm = ax[1].contourf(xkm, ykm, ups, np.arange(-50, 51, 5)) cs = ax[1].contour(xkm, ykm, ups, np.arange(-50, 51, 5), colors='k') ax[1].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[1]) ax[1].plot(cx, cy, 'w') ax[1].plot(2 * cx, 2 * cy, 'w') ax[1].set_xlabel("ups") #ax[2].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[2].set_xlim([-100, 100]) ax[2].set_ylim([-100, 100]) levels = np.arange(-20, 21, 2) cm = ax[2].contourf(xkm, ykm, ums, np.arange(-50, 51, 5)) cs = ax[2].contour(xkm, ykm, ums, np.arange(-50, 51, 5), colors='k') ax[2].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[2]) ax[2].plot(cx, cy, 'w') ax[2].plot(2 * cx, 2 * cy, 'w') ax[2].set_xlabel("ums") # Total surface wind in (moving coordinate system) us = (u0s + ups + ums) vs = V + (v0s + vps + vms) #ax[3].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[3].set_xlim([-100, 100]) ax[3].set_ylim([-100, 100]) levels = np.arange(-20, 21, 2) cm = ax[3].contourf(xkm, ykm, us, np.arange(-50, 51, 5)) cs = ax[3].contour(xkm, ykm, us, np.arange(-50, 51, 5), colors='k') ax[3].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[3]) ax[3].plot(cx, cy, 'w') ax[3].plot(2 * cx, 2 * cy, 'w') ax[3].set_xlabel("us") fig.tight_layout() plt.savefig("radial_components.png") # Total surface wind in stationary coordinate system (f for fixed) usf = us + Umod * np.cos(lam - thetaFm) vsf = vs - Umod * np.sin(lam - thetaFm) Uf = +Umod * np.cos(lam) Vf = V - Umod * np.sin(lam) phi = np.arctan2(usf, vsf) Ux = np.sqrt(usf**2. + vsf**2.) * np.sin(phi - lam) Vy = np.sqrt(usf**2. + vsf**2.) * np.cos(phi - lam) #Figure 1 here fig, axes = plt.subplots(2, 2, subplot_kw={'aspect': 'equal'}, figsize=(18, 18)) ax = axes.flatten() #plt.clf() #plt.subplot(221, aspect='equal') #plt.cla() #ax[0].hold(True) #set(plt.gca(),'DataAspectRatio',[1,1,1]) ax[0].set_xlim([-150, 150]) ax[0].set_ylim([-150, 150]) levels = np.arange(-20, 21, 2) cm = ax[0].contourf(xkm, ykm, usf, np.arange(-50., 51, 2)) cs = ax[0].contour(xkm, ykm, usf, np.arange(-50, 51, 2), colors='k') ax[0].clabel(cs, fontsize='x-small', fmt='%1.2f') #, range(-20,11,4)) plt.colorbar(cm, ax=ax[0]) ax[0].plot(cx, cy, 'w') ax[0].plot(2 * cx, 2 * cy, 'w') ax[0].set_xlabel('Storm-relative surface u') #plt.subplot(222, aspect='equal') #plt.cla() #plt.hold(True) ax[1].set_xlim([-150, 150]) ax[1].set_ylim([-150, 150]) cm = ax[1].contourf(xkm, ykm, vsf, range(-100, 101, 5)) cs = ax[1].contour(xkm, ykm, vsf, range(-100, 101, 5), colors='k') ax[1].clabel(cs, fontsize='x-small', fmt='%1.2f') plt.colorbar(cm, ax=ax[1]) ax[1].plot(cx, cy, 'w') ax[1].plot(2 * cx, 2 * cy, 'w') ax[1].set_xlabel('Storm-relative surface v') #plt.subplot(223, aspect='equal') #plt.cla() #plt.hold(True) ax[2].set_xlim([-150, 150]) ax[2].set_ylim([-150, 150]) cm = ax[2].contourf(xkm, ykm, Ux, range(-100, 101, 5)) cs = ax[2].contour(xkm, ykm, Ux, range(-100, 101, 5), colors='k') ax[2].clabel(cs, fontsize='x-small', fmt='%1.2f') #,range(-20,11,4)) plt.colorbar(cm, ax=ax[2]) ax[2].plot(cx, cy, 'w') ax[2].plot(2 * cx, 2 * cy, 'w') ax[2].set_xlabel('Earth-relative surface u (cartesian)') #plt.subplot(224, aspect='equal') #plt.cla() #plt.hold(True) ax[3].set_xlim([-150, 150]) ax[3].set_ylim([-150, 150]) cm = ax[3].contourf(xkm, ykm, Vy, range(-100, 101, 5)) cs = ax[3].contour(xkm, ykm, Vy, range(-100, 101, 5), colors='k') ax[3].clabel(cs, fontsize='x-small', fmt='%1.2f') #,h,range(0,51,10) plt.colorbar(cm, ax=ax[3]) ax[3].plot(cx, cy, 'w') ax[3].plot(2 * cx, 2 * cy, 'w') ax[3].set_xlabel('Earth-relative surface v (cartesian)') fig.suptitle('V_m=' + repr(vm) + ' r_m=' + repr(rm*1e-3) + ' b=' + repr(b) + \ ' lat=' + repr(lat) + ' K=' + repr(K) + ' C=' + repr(C)) fig.tight_layout() plt.savefig('sfc_wind_components.png') # Four possible surface wind factors \ depending on whether you # use the total or azimuthal wind, and in moving or fixed coordinates. swf1 = np.abs(vs / V) swf2 = np.abs(np.sqrt(us**2 + vs**2) / V) swf3 = np.abs(vsf / Vf) swf4 = np.sqrt(usf**2 + vsf**2) / np.sqrt(Uf**2 + Vf**2) plt.clf() plt.subplot(111, aspect='equal') #plt.hold(True) plt.xlim([-150, 150]) plt.ylim([-150, 150]) mag = np.sqrt(Ux**2 + Vy**2) # Magnitude of the total surface wind cm = plt.contourf(xkm, ykm, mag, levels=np.arange(0, 101, 5)) cs = plt.contour(xkm, ykm, mag, levels=np.arange(0, 101, 5), colors='k') plt.barbs(xkm[::5, ::5], ykm[::5, ::5], Ux[::5, ::5], Vy[::5, ::5], flip_barb=True) plt.clabel(cs, fontsize='x-small', fmt='%1.1f') plt.colorbar(cm) plt.plot(cx, cy, 'w') plt.plot(2 * cx, 2 * cy, 'w') plt.xlabel('Earth-relative total surface wind speed') plt.tight_layout() plt.savefig('sfc_total_wind.png') #Figure 2 here #figure(2) plt.clf() plt.subplot(221, aspect='equal') plt.cla() #plt.hold(True) plt.xlim([-150, 150]) plt.ylim([-150, 150]) cm = plt.contourf(xkm, ykm, swf1, levels=np.arange(0.5, 1.55, 0.05)) cs = plt.contour(xkm, ykm, swf1, np.arange(0.5, 1.55, 0.05), colors='k') plt.clabel(cs) plt.colorbar(cm) plt.plot(cx, cy, 'w') plt.plot(2 * cx, 2 * cy, 'w') plt.xlabel('Storm-relative azimuthal swrf') plt.title('V_m=' + repr(vm) + ' r_m=' + repr(rm*1e-3) + ' b=' + repr(b) + \ ' lat=' + repr(lat) + ' K=' + repr(K) + ' C=' + repr(C)) plt.subplot(222, aspect='equal') plt.cla() #plt.hold(True) plt.xlim([-150, 150]) plt.ylim([-150, 150]) cm = plt.contourf(xkm, ykm, swf2, levels=np.arange(0.5, 1.55, 0.05)) cs = plt.contour(xkm, ykm, swf2, np.arange(0.5, 1.55, 0.05), colors='k') plt.clabel(cs) plt.colorbar(cm) plt.plot(cx, cy, 'w') plt.plot(2 * cx, 2 * cy, 'w') plt.xlabel('Storm-relative total swrf') plt.subplot(223, aspect='equal') plt.cla() #plt.hold(True) plt.xlim([-150, 150]) plt.ylim([-150, 150]) cm = plt.contourf(xkm, ykm, swf3, levels=np.arange(0.5, 1.55, 0.05)) cs = plt.contour(xkm, ykm, swf3, np.arange(0.5, 1.55, 0.05), colors='k') plt.clabel(cs) plt.colorbar(cm) plt.plot(cx, cy, 'w') plt.plot(2 * cx, 2 * cy, 'w') plt.xlabel('Earth-relative azimuthal swrf') plt.subplot(224, aspect='equal') plt.cla() #plt.hold(True) plt.xlim([-150, 150]) plt.ylim([-150, 150]) cm = plt.contourf(xkm, ykm, swf4, levels=np.arange(0.5, 1.55, 0.05)) cs = plt.contour(xkm, ykm, swf4, levels=np.arange(0.5, 1.55, 0.05), colors='k') plt.clabel(cs) plt.colorbar(cm) plt.plot(cx, cy, 'w') plt.plot(2 * cx, 2 * cy, 'w') plt.xlabel('Earth-relative total swrf') plt.tight_layout() plt.savefig('swrf.png') # Coefficients p_k for k = 0, 1, -1. p0 = -(1 + i) * (al * be)**(1. / 4.) pp = -(1 + i) * np.sqrt(np.sqrt(al * be) + gam) pm = -(1 + i) * np.sqrt(np.abs(np.sqrt(al * be) - gam)) pm[III] = -i * pm[III] # Set up a 3-d grid and calculate winds nz = 400 z = np.arange(5, nz * 5 + 1, 5) [ny, nx] = x.shape u = np.zeros((nz, ny, nx), float) v = np.zeros((nz, ny, nx), float) ua = np.zeros((nz, ny, nx), float) va = np.zeros((nz, ny, nx), float) ux = np.zeros((nz, ny, nx), float) # x for cartesian wind vx = np.zeros((nz, ny, nx), float) uxa = np.zeros((nz, ny, nx), float) # Asymmetric parts have trailing a vxa = np.zeros((nz, ny, nx), float) # for kk in range(1,nz+1): for kk in range(nz): # These w's are really omega's! wm = Am * np.exp(z[kk] * pm - i * lam * np.sign(f)) # wm[fixup] = np.nan w0 = np.sign(f) * A0 * np.exp(z[kk] * p0) # w0[fixup] = np.nan wp = Ap * np.exp(z[kk] * pp + i * lam * np.sign(f)) # wp[fixup] = np.nan u[kk] = albe * (np.sign(f) * wm + w0 + np.sign(f) * wp).real v[kk] = V + (np.sign(f) * wm + w0 + np.sign(f) * wp).imag ua[kk] = np.sign(f) * albe * (np.sign(f) * wm + np.sign(f) * wp).real va[kk] = (np.sign(f) * wm + np.sign(f) * wp).imag # ux[kk] = (squeeze(u[kk])*x - squeeze(v[kk])*y) / r # vx[kk] = (squeeze(v[kk])*x + squeeze(u[kk])*y) / r # uxa[kk] = (squeeze(ua[kk])*x - squeeze(va[kk])*y) / r # vxa[kk] = (squeeze(va[kk])*x + squeeze(ua[kk])*y) / r ux[kk] = (u[kk] * x - v[kk] * y) / r vx[kk] = (v[kk] * x + u[kk] * y) / r uxa[kk] = (ua[kk] * x - va[kk] * y) / r vxa[kk] = (va[kk] * x + ua[kk] * y) / r ucon = np.arange(-20, 21, 2) vcon = np.arange(-100, 101, 5) # Figure 3 here plt.figure(6) plt.clf() plt.subplot(221) plt.cla() lp = 60 cm = plt.contourf(xx, z, np.squeeze(u[:, lp + 1, :]), ucon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(u[:, lp + 1, :]), levels=[0], colors='k', linewidths=2) plt.colorbar(cm) plt.xlabel('Storm-relative u WE section') plt.title(r'$V_m=$' + repr(vm) + r' $r_m=$' + repr(rm*1e-3) + r' $b=$' + repr(b) + \ ' lat=' + repr(lat) + ' K=' + repr(K) + ' C=' + repr(C) + \ r' $V_t=$' + repr(Ut)) plt.subplot(222) plt.cla() cm = plt.contourf(xx, z, np.squeeze(u[:, :, lp + 1]), levels=ucon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(u[:, :, lp + 1]), levels=[0], colors='k', linewidths=2) plt.colorbar(cm) plt.xlabel('Storm-relative u SN section') plt.subplot(223) plt.cla() cm = plt.contourf(xx, z, np.squeeze(v[:, lp + 1, :]), vcon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(v[:, lp + 1, :]), levels=[0], colors='k') plt.colorbar(cm) plt.xlabel('Storm-relative v WE section') plt.subplot(224) plt.cla() cm = plt.contourf(xx, z, np.squeeze(v[:, :, lp + 1]), vcon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(v[:, :, lp + 1]), levels=[0], colors='k', linewidths=2) plt.colorbar(cm) plt.xlabel('Storm-relative v SN section') plt.tight_layout() plt.savefig('xsection.png') ucon = np.arange(-100, 101, 5) vcon = np.arange(-100, 101, 5) plt.figure(7) plt.clf() plt.subplot(221) plt.cla() lp = 60 cm = plt.contourf(xx, z, np.squeeze(ux[:, lp + 1, :]), ucon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(ux[:, lp + 1, :]), levels=[0], colors='k', linewidths=2) plt.colorbar(cm) plt.xlabel('Earth-relative u WE section') plt.title(r'$V_m=$' + repr(vm) + r' $r_m=$' + repr(rm*1e-3) + r' $b=$' + repr(b) + \ ' lat=' + repr(lat) + ' K=' + repr(K) + ' C=' + repr(C) + \ r' $V_t=$' + repr(Ut)) plt.subplot(222) plt.cla() cm = plt.contourf(xx, z, np.squeeze(ux[:, :, lp + 1]), levels=ucon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(ux[:, :, lp + 1]), levels=[0], colors='k', linewidths=2) plt.colorbar(cm) plt.xlabel('Earth-relative u SN section') plt.subplot(223) plt.cla() cm = plt.contourf(xx, z, np.squeeze(vx[:, lp + 1, :]), vcon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(vx[:, lp + 1, :]), levels=[0], colors='k') plt.colorbar(cm) plt.xlabel('Earth-relative v WE section') plt.subplot(224) plt.cla() cm = plt.contourf(xx, z, np.squeeze(vx[:, :, lp + 1]), vcon) #plt.hold(True) cs = plt.contour(xx, z, np.squeeze(vx[:, :, lp + 1]), levels=[0], colors='k', linewidths=2) plt.colorbar(cm) plt.xlabel('Earth-relative v SN section') plt.tight_layout() plt.savefig('xsection_fixed.png') self.rm = rm self.vm = vm self.b = b self.lat = lat self.rho = rho self.dp = dp self.pe = pe self.f = f self.Vt = Vt self.V = V self.Z = Z self.us = us self.vs = vs self.usf = usf self.vsf = vsf self.Uf = Uf self.Vf = Vf self.swf1 = swf1 self.swf2 = swf2 self.swf3 = swf3 self.swf4 = swf4 self.u = u self.v = v
def plot_wind(axes, z, p, u, v, x=0): for i in np.arange(0,len(z),1): if (p[i] > pt_plot): plt.barbs(x,p[i],u[i],v[i], length=5, linewidth=.5)
def plot_points(self,storm,recon_data,domain="dynamic",varname='wspd',barbs=False,scatter=False,\ ax=None,return_ax=False,prop={},map_prop={}): r""" Creates a plot of recon data points Parameters ---------- recon_data : dataframe Recon data, must be dataframe domain : str Domain for the plot. Can be one of the following: "dynamic" - default. Dynamically focuses the domain using the tornado track(s) plotted. "north_atlantic" - North Atlantic Ocean basin "conus", "east_conus" "lonW/lonE/latS/latN" - Custom plot domain ax : axes Instance of axes to plot on. If none, one will be generated. Default is none. return_ax : bool Whether to return axis at the end of the function. If false, plot will be displayed on the screen. Default is false. prop : dict Property of storm track lines. map_prop : dict Property of cartopy map. """ if not barbs and not scatter: scatter = True #Set default properties default_prop={'cmap':'category','levels':(np.min(recon_data[varname]),np.max(recon_data[varname])),\ 'sortby':varname,'linewidth':1.5,'ms':7.5} default_map_prop={'res':'m','land_color':'#FBF5EA','ocean_color':'#EDFBFF',\ 'linewidth':0.5,'linecolor':'k','figsize':(14,9),'dpi':200} #Initialize plot prop = self.add_prop(prop,default_prop) map_prop = self.add_prop(map_prop,default_map_prop) self.plot_init(ax,map_prop) #set default properties input_prop = prop input_map_prop = map_prop #-------------------------------------------------------------------------------------- #Keep record of lat/lon coordinate extrema max_lat = None min_lat = None max_lon = None min_lon = None #Retrieve storm data storm_data = storm.dict vmax = storm_data['vmax'] styp = storm_data['type'] sdate = storm_data['date'] #Check recon_data type if isinstance(recon_data,pd.core.frame.DataFrame): pass else: raise RuntimeError("Error: recon_data must be dataframe") #Retrieve storm data lats = recon_data['lat'] lons = recon_data['lon'] #Add to coordinate extrema if max_lat == None: max_lat = max(lats) else: if max(lats) > max_lat: max_lat = max(lats) if min_lat == None: min_lat = min(lats) else: if min(lats) < min_lat: min_lat = min(lats) if max_lon == None: max_lon = max(lons) else: if max(lons) > max_lon: max_lon = max(lons) if min_lon == None: min_lon = min(lons) else: if min(lons) < min_lon: min_lon = min(lons) #Plot recon data as specified cmap,clevs = get_cmap_levels(varname,prop['cmap'],prop['levels']) if varname in ['vmax','sfmr','fl_to_sfc'] and prop['cmap'] == 'category': vmin = min(clevs); vmax = max(clevs) else: vmin = min(prop['levels']); vmax = max(prop['levels']) if barbs: dataSort = recon_data.sort_values(by='wspd').reset_index(drop=True) norm = mlib.colors.Normalize(vmin=min(prop['levels']), vmax=max(prop['levels'])) cmap = mlib.cm.get_cmap(prop['cmap']) colors = cmap(norm(dataSort['wspd'].values)) colors = [tuple(i) for i in colors] qv = plt.barbs(dataSort['lon'],dataSort['lat'],\ *uv_from_wdir(dataSort['wspd'],dataSort['wdir']),color=colors,length=5,linewidth=0.5) # qv.set_path_effects([patheffects.Stroke(linewidth=2, foreground='white'), # patheffects.Normal()]) # if scatter: dataSort = recon_data.sort_values(by=prop['sortby'],ascending=(prop['sortby']!='p_sfc')).reset_index(drop=True) cbmap = plt.scatter(dataSort['lon'],dataSort['lat'],c=dataSort[varname],\ cmap=cmap,vmin=vmin,vmax=vmax, s=prop['ms']) #-------------------------------------------------------------------------------------- #Storm-centered plot domain if domain == "dynamic": bound_w,bound_e,bound_s,bound_n = self.dynamic_map_extent(min_lon,max_lon,min_lat,max_lat) self.ax.set_extent([bound_w,bound_e,bound_s,bound_n], crs=ccrs.PlateCarree()) #Pre-generated or custom domain else: bound_w,bound_e,bound_s,bound_n = self.set_projection(domain) #Determine number of lat/lon lines to use for parallels & meridians self.plot_lat_lon_lines([bound_w,bound_e,bound_s,bound_n]) #-------------------------------------------------------------------------------------- #Add left title type_array = np.array(storm_data['type']) idx = np.where((type_array == 'SD') | (type_array == 'SS') | (type_array == 'TD') | (type_array == 'TS') | (type_array == 'HU')) tropical_vmax = np.array(storm_data['vmax'])[idx] subtrop = classify_subtrop(np.array(storm_data['type'])) peak_idx = storm_data['vmax'].index(np.nanmax(tropical_vmax)) peak_basin = storm_data['wmo_basin'][peak_idx] storm_type = get_storm_type(np.nanmax(tropical_vmax),subtrop,peak_basin) dot = u"\u2022" if barbs: vartitle = get_recon_title('wspd') if scatter: vartitle = get_recon_title(varname) self.ax.set_title(f"{storm_type} {storm_data['name']}\n" + 'Recon: '+' '.join(vartitle),loc='left',fontsize=17,fontweight='bold') #Add right title start_date = dt.strftime(min(recon_data['time']),'%H:%M UTC %d %b %Y') end_date = dt.strftime(max(recon_data['time']),'%H:%M UTC %d %b %Y') self.ax.set_title(f'Start ... {start_date}\nEnd ... {end_date}',loc='right',fontsize=13) #-------------------------------------------------------------------------------------- #Add legend #Phantom legend handles=[] for _ in range(10): handles.append(mlines.Line2D([], [], linestyle='-',label='',lw=0)) l = self.ax.legend(handles=handles,loc='upper left',fancybox=True,framealpha=0,fontsize=11.5) plt.draw() #Get the bbox bb = l.legendPatch.get_bbox().inverse_transformed(self.fig.transFigure) bb_ax = self.ax.get_position() #Define colorbar axis cax = self.fig.add_axes([bb.x0+bb.width, bb.y0-.05*bb.height, 0.015, bb.height]) # cbmap = mlib.cm.ScalarMappable(norm=norm, cmap=cmap) cbar = self.fig.colorbar(cbmap,cax=cax,orientation='vertical',\ ticks=clevs) if len(prop['levels'])>2: cax.yaxis.set_ticks(np.linspace(min(clevs),max(clevs),len(clevs))) cax.yaxis.set_ticklabels(clevs) else: cax.yaxis.set_ticks(clevs) cax.tick_params(labelsize=11.5) cax.yaxis.set_ticks_position('left') rect_offset = 0.0 if prop['cmap']=='category' and varname=='sfmr': cax.yaxis.set_ticks(np.linspace(min(clevs),max(clevs),len(clevs))) cax.yaxis.set_ticklabels(clevs) cax2 = cax.twinx() cax2.yaxis.set_ticks_position('right') cax2.yaxis.set_ticks((np.linspace(0,1,len(clevs))[:-1]+np.linspace(0,1,len(clevs))[1:])*.5) cax2.set_yticklabels(['TD','TS','Cat-1','Cat-2','Cat-3','Cat-4','Cat-5'],fontsize=11.5) cax2.tick_params('both', length=0, width=0, which='major') cax.yaxis.set_ticks_position('left') rect_offset = 0.7 rectangle = mpatches.Rectangle((bb.x0,bb.y0-0.1*bb.height),(1.8+rect_offset)*bb.width,1.1*bb.height,\ fc = 'w',edgecolor = '0.8',alpha = 0.8,\ transform=self.fig.transFigure, zorder=2) self.ax.add_patch(rectangle) #Add plot credit text = self.plot_credit() self.add_credit(text) #Return axis if specified, otherwise display figure if ax != None or return_ax == True: return self.ax,'/'.join([str(b) for b in [bound_w,bound_e,bound_s,bound_n]]) else: plt.show() plt.close()
## W-Component vertical Wind Contour Fill (colored) plt.contourf(x,y,masked_W,cmap='bwr',levels=np.arange(-5,5.1,.5),extend='both') cbar_loc = plt.colorbar(shrink=.8,ticks= np.arange(-5,5.1,1)) cbar_loc.ax.set_ylabel('Vertical Velocity Wind on model level 7 (m/s)\n Approx. '+str(int(center_valley_height))+' meters',fontsize=20) cbar_loc.ax.tick_params(labelsize=20) ## Contour Lake Outline plt.contour(x,y,landmask, [0,1], linewidths=3, colors="b") #plt.contour(x,y,HGT) #plt.contourf(x,y,HGT,cmap=cmapgrey) # transparent greay if plotted on top ## Wind Barbs surface plt.barbs(x[::3,::3],y[::3,::3],masked_U10[::3,::3],masked_V10[::3,::3], length=6, barb_increments=dict(half=1, full=2, flag=10), sizes=dict(emptybarb=.1), zorder=40) plt.title('Surface wind barbs with \n vertical velocity on model level 7 (~2300 m)') else: ## W-Component vertical Wind Contour Fill (colored) plt.contourf(x,y,masked_W,cmap='bwr',levels=np.arange(-5,5.1,.5),extend='both') cbar_loc = plt.colorbar(shrink=.8,ticks= np.arange(-5,5.1,1)) cbar_loc.ax.set_ylabel('Vertical Velocity Wind on model level '+str(model_level)+' (m/s)\n Approx. '+str(int(center_valley_height))+' meters',fontsize=20) cbar_loc.ax.tick_params(labelsize=20) ## Contour Lake Outline plt.contour(x,y,landmask, [0,1], linewidths=3, colors="b") #plt.contour(x,y,HGT)
import numpy as np # north-south speed # we define speed of the wind from south to north # in knots (nautical miles per hour) V = [0, -5, -10, -15, -30, -40, -50, -60, -100] # helper to coordinate size of other values with size of V vector SIZE = len(V) # east-west speed # we define speed of the wind in east-west direction # here, the "horizontal" speed component is 0 # our staff part of the wind barbs is vertical U = np.zeros(SIZE) # lon, lat # we define linear distribution in horizontal manner # of wind barbs, to spot increase in speed as we read figure from left to right y = np.ones(SIZE) x = [0, 5, 10, 15, 30, 40, 50, 60, 100] # plot the barbs plt.barbs(x, y, U, V, length=9) # misc settings plt.xticks(x) plt.ylim(0.98, 1.05) plt.show()
# Total Irradiance dataTi=dataKis+dataKil #====== Plot Temperature plt.subplot(2,2,1) plt.title('Surface Temperature (K)') # contour land CL1=plt.contour(lons,lats,dataLand,levels=[0],colors = 'k') # contour Temperature CT1=plt.contourf(lons,lats,dataT2m,cmap=get_cmap('BuRd'))# filed contour plt.colorbar(CT1) # wind barbs Cwind1=plt.barbs(X,Y,U,V,length=Lbarbs, barbcolor=['k'],pivot='middle',sizes=dict(emptybarb=0)) #====== Plot Humidity plt.subplot(2,2,2) plt.title('Relative Humidity (%)') # contour land CL2=plt.contour(lons,lats,dataLand,levels=[0],colors = 'k') # contour humidity CH2=plt.contourf(lons,lats,dataH2m,cmap=get_cmap('Blues'))# contour line plt.colorbar(CH2) # wind barbs Cwind2=plt.barbs(X,Y,U,V,length=Lbarbs, barbcolor=['k'],pivot='middle',sizes=dict(emptybarb=0)) #====== Plot Precipitation
# Download and add the states and coastlines. states = NaturalEarthFeature(category='cultural', scale='50m', facecolor='none',name='admin_0_countries') ax.coastlines('50m', linewidth=1.7) ax.add_feature(cfeature.BORDERS,linewidth=1.7) # Make the contour outlines and filled contours for the smoothed Sea Level Pressure. clevs1 = np.arange(980,1040.,2.) c1 = ax.contour(lons, lats, to_np(smooth_slp), levels=clevs1, colors="white",transform=crs.PlateCarree(), linewidths=1.3) # Make the contour outlines and filled contours for the Latent Heat Flux. clevs2 = np.arange(-100,650.,5.) c2 = plt.contourf(to_np(lons), to_np(lats), to_np(lh), clevs2, transform=crs.PlateCarree(),cmap=cm.thermal) plt.colorbar(ax=ax, shrink=.62,orientation='horizontal',aspect=20,fraction=0.046, pad=0.04) # Plot the wind barbs for the U10 and V10 from UVMET10. c3 = plt.barbs(to_np(lons[::75,::75]), to_np(lats[::75,::75]), to_np(u10[::75, ::75]), to_np(v10[::75, ::75]),color='black',transform=crs.PlateCarree(), length=6) # Set the map limits. Not really necessary, but used for demonstration. ax.set_xlim(cartopy_xlim(smooth_slp)) ax.set_ylim(cartopy_ylim(smooth_slp)) # Add the gridlines. g1 = ax.gridlines(color="gray", linestyle="--",draw_labels=True,linewidth=0.2) g1.xlabels_top = False g1.ylabels_right= False # Save. plt.title("COA_WRS (ROMS+WRF+SWAN)") plt.savefig('/home/uesleisutil/Documentos/IntegraI/slp_200.png',dpi=200,bbox_inches='tight')
'rh':obs_rh, 'mixing ratio':obs_mixing, 'wdir':obs_wdir, 'wspd':obs_wspd, 'theta': obs_theta, 'u':obs_u, 'v':obs_v } return a if __name__=="__main__": import matplotlib.pyplot as plt request_date = datetime(2016,6,13,0) a = get_sounding(request_date) # plot a simple vertical profile plt.grid() plt.plot(a['temp'],a['height'], c='r', label='Temp') plt.plot(a['dwpt'],a['height'], c='g', label='Dwpt') plt.barbs(np.zeros_like(a['temp'])[::5],a['height'][::5],a['u'][::5],a['v'][::5], label='Wind') plt.legend() plt.title("%s %s" % (a['station'],a['DATE'])) plt.xlabel('Temperture (C)') plt.ylabel('Height (m)')
def plot_wind_barbs(axes, z, p, u, v): for i in np.arange(0,len(z)): if (p[i] > pt_plot): plt.barbs(0,p[i],u[i],v[i], length=5, linewidth=.5)
def plotModelOutput(api): #Plots the data gfsLink = "http://www.nws.noaa.gov/cgi-bin/mos/getmav.pl?sta=KMSN" namLink = "http://www.nws.noaa.gov/cgi-bin/mos/getmet.pl?sta=KMSN" #day 1 gfsHours1, gfsTemps1, gfsWind1, gfsXWind1, gfsYWind1, gfsDewpoints1, day1, gfsRH1, gfsPoP1 = daydata(gfsLink, 1) namHours1, namTemps1, namWind1, namXWind1, namYWind1, namDewpoints1, day1, namRH1, namPoP1 = daydata(namLink, 1) #day2 gfsHours2, gfsTemps2, gfsWind2, gfsXWind2, gfsYWind2, gfsDewpoints2, day1, gfsRH2, gfsPoP2 = daydata(gfsLink, 2) namHours2, namTemps2, namWind2, namXWind2, namYWind2, namDewpoints2, day1, namRH2, namPoP2 = daydata(namLink, 2) #day3 gfsHours3, gfsTemps3, gfsWind3, gfsXWind3, gfsYWind3, gfsDewpoints3, day1, gfsRH3, gfsPoP3 = daydata(gfsLink, 3) namHours3, namTemps3, namWind3, namXWind3, namYWind3, namDewpoints3, day1, namRH3, namPoP3 = daydata(namLink, 3) def xlabels(startday, endday): #gets the x labels for each subplot hours = np.arange(24*startday, 24*endday, 6) labels = [] for i in range(len(hours)): labels.append(str(hours[i]-24*startday) + ':00') return hours, labels #for axis scaling maxT = max(max(gfsTemps1), max(gfsTemps2), max(gfsTemps3), max(namTemps1), max(namTemps2), max(namTemps3)) minDewpoint = min(min(gfsDewpoints1), min(gfsDewpoints2), min(gfsDewpoints3), min(namDewpoints1), min(namDewpoints2), min(namDewpoints3)) maxWind = max(max(gfsWind1), max(gfsWind2), max(gfsWind3), max(namWind1), max(namWind2), max(namWind3)) hours, xlabel = xlabels(0,1) fig = plt.figure(figsize=(10,8)) plt.rcParams['xtick.labelsize'] = 17 plt.rcParams['ytick.labelsize'] = 17 plt.rcParams['lines.linewidth'] = 3 plt.rcParams['ytick.color'] = 'k' plt.rcParams['xtick.color'] = 'k' ax = fig.add_subplot(111) plt.subplots_adjust(hspace=0.7, left = 0.0, right = 0.99, bottom = 0.0, wspace = 0.15) plt.style.use('fivethirtyeight') plt.title('Model Output Statistics (MOS): Madison, WI\n\n', fontsize = 25, color = 'k', ) text = """This data is generated from the two major weather models run in the US: the North American model (NAM) and the Global Forecast System (GFS). While this data can be beneficial in seeing what the weather will be like in certain places around the US, it can sometimes lead to large forecasting errors, which is why this is meant to serve as a GUIDE rather than an absolute forecast. Check with your local forecasting office for the most accurate weather predictions. To learn more information about MOS products, check out the following links: http://www.nws.noaa.gov/mdl/synop/products.php, http://www.nws.noaa.gov/mdl/synop/mavcard.php To learn how to interpret wind barbs, check out the following link: http://weather.rap.ucar.edu/info/about_windbarb.html""" ax.text(-0.05, -0.08, text, verticalalignment='top', horizontalalignment='left', transform=ax.transAxes, color='k', fontsize=15) plt.axis('off') #DAY 1 Temperature/Dew Point ax1 = fig.add_subplot(2,3,1) plt.title('Day 1: ' + str(day1) + '\n' + str(min(gfsHours1[0], namHours1[0])) + ':00 - 11:59 PM', fontsize = 17) ax1.plot(gfsHours1, gfsTemps1, 'firebrick', label = 'GFS') ax1.plot(gfsHours1, gfsDewpoints1, color = 'firebrick', linestyle = '--') plt.axis([min(min(gfsHours1), min(namHours1)), 24, minDewpoint - 5, maxT + 5], fontsize = 15) plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, fontsize = 15, fontweight = 'bold', color = 'k') plt.yticks(fontweight = 'bold', color = 'k') plt.ylabel("Temperature (F)", fontsize = 15, fontweight = 'bold', color = 'k') ax2 = ax1.twiny() ax2.plot(namHours1, namTemps1, 'slateblue', label = 'NAM') ax2.plot(namHours1, namDewpoints1, color = 'slateblue', linestyle = '--') plt.axis([min(min(gfsHours1), min(namHours1)), 24, minDewpoint - 5, maxT + 5]) plt.axis('off') plt.legend(bbox_to_anchor=(0.0, 1.0), loc=2, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, fontsize = 15, fontweight = 'bold', color = 'k') #DAY 1 Winds (unwanted, too many graphs) #ax1 = fig.add_subplot(3,3,4) #plt.title('Day 1: Wind Speed and Direction.\nValid ' + str(day1) + ' ' # + str(min(gfsHours1[0], namHours1[0])) + ':00 - 11:59 PM', fontsize = 18) #ax1.bar(gfsHours1, gfsWind1, width = 0.70, color = 'red', label = 'GFS') #ax1.bar(np.array(namHours1)-0.70, namWind1, width = 0.70, color = 'b', label = 'NAM') #plt.barbs(gfsHours1, 0, gfsXWind1, gfsYWind1, linewidth = 1.25, color = 'red') #plt.barbs(namHours1, 0, namXWind1, namYWind1, linewidth = 1.25, color = 'b') #plt.hlines(0, 0, max(gfsHours1), color = 'k') #plt.axis([min(min(gfsHours1), min(namHours1))-4, 24, # -10, 10]) #plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') #plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) #plt.yticks(np.arange(0,max(max(gfsWind1), max(namWind1)), 5), fontweight = 'bold', color = 'k') #plt.ylabel("Wind Speed (knots)", fontsize = 15, labelpad = -3, fontweight = 'bold', color = 'k') #DAY 1 Relative Humidity, precip potential ax1 = fig.add_subplot(2,3,4) plt.title('Day 1: ' + str(day1) + '\n' + str(min(gfsHours1[0], namHours1[0])) + ':00 - 11:59 PM', fontsize = 17) ax1.plot(gfsHours1, gfsRH1, 'firebrick') plt.axis([min(min(gfsHours1), min(namHours1)), 24, 0, 100]) ax1.bar(gfsHours1, gfsPoP1, width = 0.70, color = 'firebrick', label = 'GFS') plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') plt.ylabel("(%)", fontsize = 15, labelpad = -4, fontweight = 'bold', color = 'k') plt.yticks(np.arange(0,101,20), fontweight = 'bold', color = 'k') ax2 = ax1.twiny() ax2.plot(namHours1, namRH1, 'slateblue') ax2.bar(np.array(namHours1)-0.70, namPoP1, width = 0.70, color = 'slateblue', label = 'NAM') plt.barbs(gfsHours1, -20, gfsXWind1, gfsYWind1, linewidth = 3, color = 'firebrick') plt.barbs(namHours1, -20, namXWind1, namYWind1, linewidth = 3, color = 'slateblue') plt.hlines(0, min(min(gfsHours1), 0), max(gfsHours1), color = 'k') plt.axis([min(min(gfsHours1), min(namHours1)), 24, -50, 100]) plt.axis('off') plt.legend(bbox_to_anchor=(0.0, 1.0), loc=2, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, color = 'k') #DAY 2 Temperature/Dew Point ax1 = fig.add_subplot(2,3,2) plt.title('Temperature & Dew Point\nDay 2: ' + str(day1 + dat.timedelta(days=1)) + '\n12:00 AM - 11:59 PM', fontsize = 17) ax1.plot(gfsHours2, gfsTemps2, 'firebrick', label = 'GFS') ax1.plot(gfsHours2, gfsDewpoints2, color = 'firebrick', linestyle = '--') plt.axis([24, 48, minDewpoint - 5, maxT + 5]) plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) hours, xlabel = xlabels(1,2) plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') plt.yticks(fontweight = 'bold', color = 'k') plt.xlabel("Time (CST)", fontsize = 15, labelpad = 5, fontweight = 'bold', color = 'k') ax2 = ax1.twiny() ax2.plot(namHours2, namTemps2, 'slateblue', label = 'NAM') ax2.plot(namHours2, namDewpoints2, color = 'slateblue', linestyle = '--') plt.axis([24, 48, minDewpoint - 5, maxT + 5]) plt.axis('off') plt.legend(bbox_to_anchor=(0.0, 1.0), loc=2, borderaxespad=0, fontsize = 12) #DAY 2 winds #ax1 = fig.add_subplot(3,3,5) #plt.title('Day 2: Wind Speed and Direction.\nValid ' + str(day1 + dat.timedelta(days=1)) # + ' 12:00 AM - 11:59 PM', fontsize = 18) #ax1.bar(gfsHours2, gfsWind2, width = 0.70, color = 'red', label = 'GFS') #ax1.bar(np.array(namHours2)-0.70, namWind2, width = 0.70, color = 'b', label = 'NAM') #plt.barbs(gfsHours2, 0, gfsXWind2, gfsYWind2, linewidth = 1.25, color = 'red') #plt.barbs(namHours2, 0, namXWind2, namYWind2, linewidth = 1.25, color = 'b') #plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) #plt.axis([22.25, 48, -10, 10]) #plt.hlines(0, 0, 48, color = 'k') #plt.yticks(np.arange(0,max(max(gfsWind1), max(namWind1)), 5), fontweight = 'bold', color = 'k') #plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') #plt.xlabel("Time (CST)", fontsize = 15, labelpad = 5, fontweight = 'bold', color = 'k') #DAY 2 Relative Humidity, precip potential ax1 = fig.add_subplot(2,3,5) plt.title('Relative humidity (line),chance of precipitation in the previous 6 hour period (bar),\nand wind barbs (knots).\nDay 2: ' + str(day1 + dat.timedelta(days=1)) + '\n12:00 AM - 11:59 PM', fontsize = 17) ax1.plot(gfsHours2, gfsRH2, 'firebrick') plt.axis([24, 48, 0, 100]) ax1.bar(gfsHours2, gfsPoP2, width = 0.70, color = 'firebrick', label = 'GFS') plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') plt.xlabel("Time (CST)", fontsize = 15, labelpad = 5, fontweight = 'bold', color = 'k') plt.yticks(np.arange(0,101,20), fontweight = 'bold', color = 'k') ax2 = ax1.twiny() plt.barbs(gfsHours2, -20, gfsXWind2, gfsYWind2, linewidth = 3, color = 'firebrick') plt.barbs(namHours2, -20, namXWind2, namYWind2, linewidth = 3, color = 'slateblue') plt.hlines(0,0,48, color = 'k') ax2.plot(namHours2, namRH2, 'slateblue') ax2.bar(np.array(namHours2)-0.70, namPoP2, width = 0.70, color = 'slateblue', label = 'NAM') plt.axis([24, 48, -50, 100]) plt.axis('off') plt.legend(bbox_to_anchor=(0.0, 1.0), loc=2, borderaxespad=0, fontsize = 12) #DAY 3 Temperature/Dew Point hours, xlabel = xlabels(2,3) ax1 = fig.add_subplot(2,3,3) plt.title('Day 3: ' + str(day1 + dat.timedelta(days=2)) + '\n12:00 AM - 11:59 PM', fontsize = 17) ax1.plot(gfsHours3, gfsTemps3, 'firebrick', label = 'GFS') ax1.plot(gfsHours3, gfsDewpoints3, color = 'firebrick', linestyle = '--') plt.axis([48, 72, minDewpoint - 5, maxT + 5]) plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') plt.yticks(fontweight = 'bold', color = 'k') ax2 = ax1.twiny() ax2.plot(namHours3, namTemps3, 'slateblue', label = 'NAM') ax2.plot(namHours3, namDewpoints3, color = 'slateblue', linestyle = '--') plt.axis([48, 72, minDewpoint - 5, maxT + 5]) plt.axis('off') plt.legend(bbox_to_anchor=(0.0, 1.0), loc=2, borderaxespad=0, fontsize = 12) #DAY 3 winds #ax1 = fig.add_subplot(3,3,6) #plt.title('Day 3: Wind Speed and Direction.\nValid ' + str(day1 + dat.timedelta(days=2)) # + ' 12:00 AM - 11:59 PM ', fontsize = 18) #ax1.bar(gfsHours3, gfsWind3, width = 0.70, color = 'red', label = 'GFS') #ax1.bar(np.array(namHours3)-0.70, namWind3, width = 0.70, color = 'b', label = 'NAM') #plt.barbs(gfsHours3, 0, gfsXWind3, gfsYWind3, linewidth = 1.25, color = 'red') #plt.barbs(namHours3, 0, namXWind3, namYWind3, linewidth = 1.25, color = 'b') #plt.hlines(0, 0, 73, color = 'k') #plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) #plt.axis([46.5, 72, -10, 10]) #plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') #plt.yticks(np.arange(0,max(max(gfsWind3), max(namWind3)), 5), fontweight = 'bold', color = 'k') #DAY 3 Relative Humidity, precip potential ax1 = fig.add_subplot(2,3,6) plt.title('Day 3: ' + str(day1 + dat.timedelta(days=2)) + '\n12:00 AM - 11:59 PM', fontsize = 16) ax1.plot(gfsHours3, gfsRH3, 'firebrick') plt.axis([46.5, 72, 0, 100]) ax1.bar(gfsHours3, gfsPoP3, width = 0.70, color = 'firebrick', label = 'GFS') plt.legend(bbox_to_anchor=(1.0, 1.0), loc=1, borderaxespad=0, fontsize = 12) plt.xticks(hours, xlabel, fontweight = 'bold', color = 'k') plt.yticks(np.arange(0,101,20),fontweight = 'bold', color = 'k') ax2 = ax1.twiny() ax2.plot(namHours3, namRH3, 'slateblue') ax2.bar(np.array(namHours3)-0.70, namPoP3, width = 0.70, color = 'slateblue', label = 'NAM') plt.barbs(gfsHours3, -20, gfsXWind3, gfsYWind3, linewidth = 3, color = 'firebrick') plt.barbs(namHours3, -20, namXWind3, namYWind3, linewidth = 3, color = 'slateblue') plt.hlines(0, 0, 73, color = 'k') plt.axis([46.5, 72, -50, 100]) plt.axis('off') plt.legend(bbox_to_anchor=(0.0, 1.0), loc=2, borderaxespad=0, fontsize = 12) plt.savefig('ModelData.png', bbox_inches = 'tight', facecolor = 'lightgray') tweet = "It's the MOSt important time of the day! Here's what the models are forecasting for the next few days." try: #plt.show() api.update_with_media("ModelData.png", status=tweet) print 'Tweet successful!' except tweepy.error.TweepError: print ("Twitter error raised") except HTTPError: print ("URL Error") plt.close('all')
import matplotlib.pyplot as plt import numpy as np x = np.linspace(-20, 20, 8) y = np.linspace(0, 20, 8) # make 2D coordinates X, Y = np.meshgrid(x, y) U, V = X + 25, Y - 35 # plot the barbs plt.subplot(1, 2, 1) plt.barbs(X, Y, U, V, flagcolor='green', alpha=0.75) plt.grid(True, color='gray') # compare that with quiver / arrows plt.subplot(1, 2, 2) plt.quiver(X, Y, U, V, facecolor='red', alpha=0.75) # misc settings plt.grid(True, color='grey') plt.show()
def plot_theta_e(ncFile, targetDir, levels, withHeights=True, withWinds=True, windScaleFactor=50): logger = PyPostTools.pyPostLogger() st, fh, fh_int = getTimeObjects(ncFile) for level in levels: fig, ax, X, Y = prepare_plot_object(ncFile) titleAdd = "" clevs = np.arange(240, 380, 5) if (level == 0): # Surface is special in regards to naming and ignoring geo.hgt. argument eth = ncFile["SFC_THETA_E"] contours = plt.contourf(X, Y, eth, clevs, cmap=get_cmap('gist_ncar'), transform=ccrs.PlateCarree()) cbar = plt.colorbar(ax=ax, orientation="horizontal", pad=.05) cbar.set_label("Equivalent Potential Temperature (K)") if (withWinds): u = ncFile["SFC_U"] v = ncFile["SFC_V"] uKT = Conversions.ms_to_kts(u) vKT = Conversions.ms_to_kts(v) plt.barbs(to_np(X[::windScaleFactor, ::windScaleFactor]), to_np(Y[::windScaleFactor, ::windScaleFactor]), to_np(uKT[::windScaleFactor, ::windScaleFactor]), to_np(vKT[::windScaleFactor, ::windScaleFactor]), transform=ccrs.PlateCarree(), length=6) titleAdd += ", Winds (Kts)" plt.title("Surface Theta-E (K)" + titleAdd) plt.text(0.02, -0.02, "Forecast Time: " + fh.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.text(0.7, -0.02, "Initialized: " + st.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.subplots_adjust(bottom=0.1) plt.savefig(targetDir + "/ThetaE_SFC_F" + str(fh_int)) plt.close(fig) else: eth = ncFile["THETA_E_" + str(level)] contours = plt.contourf(X, Y, eth, clevs, cmap=get_cmap('gist_ncar'), transform=ccrs.PlateCarree()) cbar = plt.colorbar(ax=ax, orientation="horizontal", pad=.05) cbar.set_label("Equivalent Potential Temperature (K)") if (withHeights == True): z = ncFile["GEOHT_" + str(level)] zDM = z / 10 smooth_lines = gaussian_filter(to_np(zDM), sigma=3) if (level <= 200): cont_levels = np.arange(800., 1600., 6.) elif (level <= 400): cont_levels = np.arange(600., 1200., 6.) elif (level <= 600): cont_levels = np.arange(200., 800., 6.) elif (level <= 800): cont_levels = np.arange(100., 600., 6.) else: cont_levels = np.arange(0., 400., 6.) contours = plt.contour(X, Y, smooth_lines, levels=cont_levels, colors="black", transform=ccrs.PlateCarree()) plt.clabel(contours, inline=1, fontsize=10, fmt="%i") titleAdd += ", Geopotential Height (dm)" if (withWinds): u = ncFile["U_" + str(level)] v = ncFile["V_" + str(level)] uKT = Conversions.ms_to_kts(u) vKT = Conversions.ms_to_kts(v) plt.barbs(to_np(X[::windScaleFactor, ::windScaleFactor]), to_np(Y[::windScaleFactor, ::windScaleFactor]), to_np(uKT[::windScaleFactor, ::windScaleFactor]), to_np(vKT[::windScaleFactor, ::windScaleFactor]), transform=ccrs.PlateCarree(), length=6) titleAdd += ", Winds (Kts)" plt.title(str(level) + "mb Theta-E (K)" + titleAdd) plt.text(0.02, -0.02, "Forecast Time: " + fh.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.text(0.7, -0.02, "Initialized: " + st.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.subplots_adjust(bottom=0.1) plt.savefig(targetDir + "/ThetaE_" + str(level) + "_F" + str(fh_int)) plt.close(fig)
14: '68-72 knots', 15: '73-77 knots', 16: '78-82 knots', 17: '83-87 knots', 18: '88-92 knots', 19: '93-97 knots', 20: '98-102 knots'} color = 'blue' kwargs = dict(length=8, color=color) lsx = 1 rsx = 3 ly = 23 delta = 0.3 plt.barbs(lsx, ly, 0, 0, **kwargs) plt.text(lsx + delta, ly, 'Calm') plt.plot([lsx - 0.36, lsx], [ly - 2, ly -2], linewidth=2, color=color) plt.text(lsx + delta, ly - 2, knots[0]) for i, u in enumerate(range(5, 50, 5)): y = ly - (i + 2) * 2 plt.barbs(lsx, y, u, 0, **kwargs) plt.text(lsx + delta, y, knots[np.searchsorted(_BARB_BINS, u, side='right')]) for i, u in enumerate(range(50, 105, 5)): y = ly - i * 2 plt.barbs(rsx, y, u, 0, **kwargs) plt.text(rsx + delta, y, knots[np.searchsorted(_BARB_BINS, u, side='right')])
def plot_surface_map(ncFile, targetDir, withTemperature=True, withWinds=True, windScaleFactor=50, withMSLP=True): logger = PyPostTools.pyPostLogger() if (withTemperature == False and withWinds == False and withMSLP == False): logger.write("Error in plot_surface_map(): Nothing to do.") return False fig, ax, X, Y = prepare_plot_object(ncFile) st, fh, fh_int = getTimeObjects(ncFile) titleAdd = "" if (withTemperature): T = ncFile["SFC_T"] TF = Conversions.K_to_F(T) clevs = np.arange(-30, 115, 5) contours = plt.contourf(X, Y, TF, clevs, cmap=ColorMaps.temp_colormap, transform=ccrs.PlateCarree()) cbar = plt.colorbar(ax=ax, orientation="horizontal", pad=.05) cbar.set_label("Temperature (F)") titleAdd += "Temperature " if (withMSLP): SLP = to_np(ncFile["MSLP"]) smooth_slp = gaussian_filter(SLP, sigma=3) levs = np.arange(950, 1050, 4) linesC = plt.contour(X, Y, smooth_slp, levs, colors="black", transform=ccrs.PlateCarree(), linewidths=1) plt.clabel(linesC, inline=1, fontsize=10, fmt="%i") titleAdd += "MSLP (mb) " if (withWinds): u = ncFile["SFC_U"] v = ncFile["SFC_V"] uKT = Conversions.ms_to_kts(u) vKT = Conversions.ms_to_kts(v) plt.barbs(to_np(X[::windScaleFactor, ::windScaleFactor]), to_np(Y[::windScaleFactor, ::windScaleFactor]), to_np(uKT[::windScaleFactor, ::windScaleFactor]), to_np(vKT[::windScaleFactor, ::windScaleFactor]), transform=ccrs.PlateCarree(), length=6) titleAdd += "Winds " # Finish things up, for the title crop off the extra comma at the end, add the time text, and save. titleAdd = titleAdd.replace(" ", ", ") titleAdd = titleAdd[:-2] plt.title("Surface Map (" + titleAdd + ")") plt.text(0.02, -0.02, "Forecast Time: " + fh.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.text(0.7, -0.02, "Initialized: " + st.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.subplots_adjust(bottom=0.1) plt.savefig(targetDir + "/sfcmap_F" + str(fh_int)) plt.close(fig) return True
def barbs(*args, **kwargs): r"""starkplot wrapper for barbs""" return _pyplot.barbs(*args, **kwargs)
count, 1] >= 118 and data[count, 0] >= 31: data_to_plot = data_to_plot + [ data[count, 1], data[count, 0], data[count, 3], data[count, 4] ] count += 1 data_to_plot = np.asarray(data_to_plot).reshape([len(data_to_plot) / 4, 4]) radar_loc = {"lon": 118.69, "lat": 32.19} radar_file_path = "/media/qzhang/240E5CF90E5CC608/2011_07_18/radar/Z_RADR_I_Z9250_20110718110000_O_DOR_SA_CAP.bin" y, fw, j, fs = radar_read(radar_file_path) nx, ny, nz = sph2cart(y, fw, j) """ ax=plt.subplot(1,1,1) ax.barbs(data[:,1],data[:,0],data[:,3],data[:,4]) plt.show() """ plt.subplot(1, 1, 1) plt.pcolor(ny, nx, fs, cmap='gist_ncar', vmin=10, vmax=75) plt.axis([-80, 160, -140, 100]) plt.colorbar(ticks=np.linspace(10, 75, 14)) plt.subplot(1, 1, 1) plt.barbs((data_to_plot[:, 0] - radar_loc["lon"]) * 110, (data_to_plot[:, 1] - radar_loc["lat"]) * 110, data_to_plot[:, 2], data_to_plot[:, 3]) plt.title("2011-07-18_11:00 UTC", fontsize=20) plt.xlabel("Longitude", fontsize=14) plt.ylabel("Latitude", fontsize=14) plt.xticks([-80, -20, 40, 100, 160], [118.0, 118.5, 119.0, 119.5, 120.0]) plt.yticks([-140, -80, -20, 40, 100], [31.0, 31.5, 32, 32.5, 33]) plt.show()
def plot_sounding(axes, z, th, p, qv, u=None, v=None): """Plot sounding data This plots temperature, dewpoint and wind data on a Skew-T/Log-P plot. This will also plot derived values such as wetbulb temperature and label the surface based LCL, LFC and EL. :parameter z: height values (1D array) :parameter th: potential temperature at z heights (1D array) :parameter p: pressure at z heights (1D array) :parameter qv: water vapor mixing ratio at z heights (1D array) :parameter u: U component of wind at z heights (1D array) :parameter v: V component of wind at z heights (1D array) :paramter axes: The axes instance to draw on """ # calculate Temperature and dewpoint T = met.T(th, p) - met.T00 # T (C) Td = met.Td(p, qv) - met.T00 # Td (C) # calculate wetbulb temperature Twb = np.empty(len(z), np.float32) # Twb (C) for zlvl in range(len(z)): Twb[zlvl] = met.Twb(z, p, th, qv, z[zlvl]) # Get surface parcel CAPE and temperature / height profiles pcl = met.CAPE(z, p, T + met.T00, qv, 1) # CAPE T_parcel = pcl['t_p'] - met.T00 # parcel T (C) T_vparcel = pcl['tv_p'] - met.T00 # parcel Tv (C) T_venv = met.T(pcl['thv_env'], pcl['pp']) - met.T00 # Env Tv (C) # plot Temperature, dewpoint, wetbulb and lifted surface parcel profiles on skew axes axes.semilogy(T + skew(p), p, basey=math.e, color=linecolor_T, linewidth=linewidth_T) axes.semilogy(Td + skew(p), p, basey=math.e, color=linecolor_Td, linewidth=linewidth_Td) axes.semilogy(T_parcel + skew(pcl['pp']), pcl['pp'], basey=math.e, color=linecolor_Parcel_T, linewidth=linewidth_Parcel_T) axes.semilogy(Twb + skew(p), p, basey=math.e, color=linecolor_Twb, linewidth=linewidth_Twb) # plot virtual temperature of environment and lifted parcel axes.semilogy(T_venv + skew(pcl['pp']), pcl['pp'], basey=math.e, color=linecolor_Tve, linewidth=linewidth_Tve, linestyle=linestyle_Tve) axes.semilogy(T_vparcel + skew(pcl['pp']), pcl['pp'], basey=math.e, color=linecolor_Tvp, linewidth=linewidth_Tvp, linestyle=linestyle_Tvp) # Add labels for levels based on surface parcel #debug print(pcl['lfcprs'], pcl['lclprs'], pcl['elprs'], pcl['ptops']) if (pcl['lfcprs'] > 0): label_m(Tmax - .5, pcl['lfcprs'], '--LFC', axes) if (pcl['lclprs'] > 0): label_m(Tmax - .5, pcl['lclprs'], '--LCL', axes) if (pcl['elprs'] > 0): label_m(Tmax - .5, pcl['elprs'], '--EL', axes) if (pcl['ptops'] > 0): label_m(Tmax - .5, pcl['ptops'], '--TOPS', axes) # plot labels for std heights for plvl in plevs_std: zlvl = pymeteo.interp.interp_height(z, p, plvl) label_m(Tmin - .5, plvl, str(int(zlvl)), axes) # plot wind barbs on left side of plot. move this? right side? if (u is not None and v is not None): #draw_wind_line(axes) for i in np.arange(0, len(z), 2): if (p[i] > pt_plot): plt.barbs(Tmin + 4, p[i], u[i], v[i], length=5, linewidth=.5)
meridional='C:/Users/Developer202/Desktop/MWR/Data/Reanalysis/Surface/vwnd.mon.mean.nc' zonal='C:/Users/Developer202/Desktop/MWR/Data/Reanalysis/Surface/uwnd.mon.mean.nc' vdata = Dataset(meridional) udata = Dataset(zonal) # read lats,lons # reverse latitudes so they go from south to north. lats = udata.variables['lat'][::-1] lons = udata.variables['lon'][:] # get sea level pressure and 10-m wind data. # mult slp by 0.01 to put in units of hPa. #slpin = 0.01*data.variables['Pressure_msl'][:].squeeze() u = udata.variables['uwnd'][:] v = vdata.variables['vwnd'][:] speed=np.sqrt(u**2+v**2) plt.barbs(lons,lats,u,v,speed) # add cyclic points manually (could use addcyclic function) #slp = np.zeros((slpin.shape[0],slpin.shape[1]+1),np.float) #slp[:,0:-1] = slpin[::-1]; slp[:,-1] = slpin[::-1,0] #u = np.zeros((uin.shape[0],uin.shape[1]+1),np.float64) #u[:,0:-1] = uin[::-1]; u[:,-1] = uin[::-1,0] #v = np.zeros((vin.shape[0],vin.shape[1]+1),np.float64) #v[:,0:-1] = vin[::-1]; v[:,-1] = vin[::-1,0] #longitudes.append(360.); longitudes = np.array(longitudes) # make 2-d grid of lons, lats #lons, lats = np.meshgrid(longitudes,latitudes) # make orthographic basemap. m = Basemap(resolution='c',projection='ortho',lat_0=60.,lon_0=-60.) # create figure, add axes fig1 = plt.figure(figsize=(8,10))
def main(folder, wrffolder, append, sourceid, plotmap, plotcurves, plotcontour, plotcontourf, plotbarbs, resol): #z_unit = 'km' z_unit = 'dm' z_unitStr = 'dam' #u_unit = 'm s-1' u_unit = 'kt' w_unit = u_unit w_unitStr = 'm/s' w_unitStr = 'kt' p_unit = 'hPa' df_obs = pd.read_csv(folder + sourceid + '_json.txt', delimiter='\t') df_obs['time'] = pd.to_datetime(df_obs['CurrentTime'], unit='s') df_obs['air_temperature'] = df_obs['Temperature'] df_obs['pressure'] = df_obs['Barometric Pressure'] df_obs['wind_speed'] = df_obs[ 'Wind Speed'] * 1.852 / 3.6 # Convert from knots to m/s if z_unit == "km": feetScale = 0.3048 / 1000 elif z_unit == "m": feetScale = 0.3048 elif z_unit == "dm": feetScale = 0.3048 / 10 df_obs['z'] = df_obs['Alt'].to_numpy( ) * feetScale # Convert from feet to decameters (dam) # Get data from WRF file i_domain = 10 isOutside = True while isOutside: if i_domain < 0: print('Parts of the flightpath for ' + str(sourceid) + ' is not inside the solution domain') break i_domain -= 1 try: ncfile = Dataset(wrffolder + '/wrfout_d0' + str(i_domain) + '.nc') except: continue fields = ['T', 'wind_speed', 'wind_from_direction'] lat_e = df_obs['Latitude'].to_numpy() lon_e = df_obs['Longitude'].to_numpy() z_e = df_obs['z'].to_numpy() time_e = df_obs['time'].to_numpy() dummy = pd.DataFrame( {'time': wrf.getvar(ncfile, 'Times', wrf.ALL_TIMES)}) time = dummy['time'].to_numpy() indices = (time[0] <= time_e) & (time_e <= time[-1]) if not np.any(indices): raise OutOfRange('The mode-S data is out of range') lat_e = lat_e[indices] lon_e = lon_e[indices] z_e = z_e[indices] time_e = time_e[indices] x = np.zeros((lat_e.shape[0], 4)) xy = wrf.ll_to_xy(ncfile, lat_e, lon_e, as_int=False, meta=False) if ncfile.MAP_PROJ_CHAR == 'Cylindrical Equidistant' and i_domain == 1: xy[0] += 360 / 0.25 x[:, 0] = xy[0] x[:, 1] = xy[1] e_we = ncfile.dimensions['west_east'].size e_sn = ncfile.dimensions['south_north'].size if np.any(xy < 0) or np.any(xy[0] > e_we - 1) or np.any( xy[1] > e_sn - 1): print('Flight path is outside domain d0' + str(i_domain)) continue else: print('Extracting WRF-data from domain d0' + str(i_domain)) if plotcurves: xy2 = np.zeros(xy.T.shape) xy2[:, :] = xy[:, :].T #zgrid = wrf.interp2dxy(wrf.getvar(ncfile,'z',units=z_unit),xy2,meta=False) zgrid = wrf.interp2dxy(wrf.g_geoht.get_height(ncfile, units=z_unit), xy2, meta=False) # Get geopotential height for i in range(0, len(z_e)): f_time = interp1d(zgrid[:, i], range(0, zgrid.shape[0]), kind='linear') x[i, 2] = f_time(z_e[i]) f_time = interp1d(time.astype('int'), range(0, len(time)), kind='linear') x[:, 3] = f_time(time_e.astype('int')) df_wrf = pd.DataFrame() df_wrf['time'] = time_e df_wrf['air_temperature'] = linInterp( wrf.getvar(ncfile, 'tc', wrf.ALL_TIMES, meta=False), x) df_wrf['pressure'] = linInterp( wrf.g_pressure.get_pressure(ncfile, wrf.ALL_TIMES, meta=False, units=p_unit), x) df_wrf['wind_speed'] = linInterp( wrf.g_wind.get_destag_wspd(ncfile, wrf.ALL_TIMES, meta=False), x) df_wrf['wind_from_direction'] = linInterp( wrf.g_wind.get_destag_wdir(ncfile, wrf.ALL_TIMES, meta=False), x) if df_wrf.isnull().values.any(): print('Some points are outside the domain ' + str(i_domain)) continue else: isOutside = False else: isOutside = False if plotcurves: # Plot data sharex = True #fields = np.array([['air_temperature','wind_speed','pressure'], # ['windDirX', 'windDirY','z']]) #ylabels = np.array([['Temperature [°C]', 'Wind speed [m/s]', 'Pressure ['+p_unit+']'], # ['Wind direction - X','Wind direction - Y', 'Altitude ['+z_unitStr+']']]) fields = np.array([['air_temperature', 'wind_speed'], ['windDirX', 'windDirY']]) ylabels = np.array([['Temperature [°C]', 'Wind speed [m/s]'], ['Wind direction - X', 'Wind direction - Y']]) df_obs['windDirX'] = np.cos(np.radians(df_obs['Wind Direction'])) df_obs['windDirY'] = np.sin(np.radians(df_obs['Wind Direction'])) df_wrf['windDirX'] = np.cos(np.radians(df_wrf['wind_from_direction'])) df_wrf['windDirY'] = np.sin(np.radians(df_wrf['wind_from_direction'])) df_wrf['z'] = z_e fig, axs = plt.subplots(fields.shape[0], fields.shape[1], sharex=sharex) mng = plt.get_current_fig_manager() #mng.resize(*mng.window.maxsize()) #mng.frame.Maximize(True) mng.window.showMaximized() title = 'Comparison between Mode-S data and WRF simulations for flight ' + sourceid if plotcurves: title += '. WRF data from domain d0' + str( i_domain) + ' with grid resolution {:.1f} km'.format( max(ncfile.DX, ncfile.DY) / 1000) fig.suptitle(title) for i in range(0, fields.shape[0]): for j in range(0, fields.shape[1]): axs[i, j].plot(df_wrf.time.to_numpy(), df_wrf[fields[i, j]].to_numpy(), 'b', label='WRF forecast') axs[i, j].plot(df_obs.time.to_numpy(), df_obs[fields[i, j]].to_numpy(), 'r', label='Observation data') axs[i, j].legend() axs[i, j].set(xlabel='Time', ylabel=ylabels[i, j]) axs[i, j].set_xlim(time_e[0], time_e[-1]) axs[1, 0].set_ylim(-1, 1) axs[1, 1].set_ylim(-1, 1) plt.show() fig.savefig(folder + '/' + sourceid + '_curves.png', dpi=400) if plotmap: # Extract the pressure, geopotential height, and wind variables ncfile = Dataset(wrffolder + '/wrfout_d01.nc') p = wrf.g_pressure.get_pressure(ncfile, units=p_unit) #p = getvar(ncfile, "pressure",units=p_unit) z = getvar(ncfile, "z", units=z_unit) ua = getvar(ncfile, "ua", units=u_unit) va = getvar(ncfile, "va", units=u_unit) wspd = getvar(ncfile, "wspd_wdir", units=w_unit)[0, :] # Interpolate geopotential height, u, and v winds to 500 hPa ht_500 = interplevel(z, p, 500) u_500 = interplevel(ua, p, 500) v_500 = interplevel(va, p, 500) wspd_500 = interplevel(wspd, p, 500) # Get the lat/lon coordinates lats, lons = latlon_coords(ht_500) # Get the map projection information cart_proj = get_cartopy(ht_500) # Create the figure fig = plt.figure(figsize=(12, 9)) ax = plt.axes(projection=cart_proj) # Download and add the states and coastlines name = 'admin_0_boundary_lines_land' #name = 'admin_1_states_provinces_lines' #name = "admin_1_states_provinces_shp" bodr = cfeature.NaturalEarthFeature(category='cultural', name=name, scale=resol, facecolor='none') land = cfeature.NaturalEarthFeature('physical', 'land', \ scale=resol, edgecolor='k', facecolor=cfeature.COLORS['land']) ocean = cfeature.NaturalEarthFeature('physical', 'ocean', \ scale=resol, edgecolor='none', facecolor=cfeature.COLORS['water']) lakes = cfeature.NaturalEarthFeature('physical', 'lakes', \ scale=resol, edgecolor='b', facecolor=cfeature.COLORS['water']) rivers = cfeature.NaturalEarthFeature('physical', 'rivers_lake_centerlines', \ scale=resol, edgecolor='b', facecolor='none') ax.add_feature(land, facecolor='beige', zorder=0) ax.add_feature(ocean, linewidth=0.2, zorder=0) ax.add_feature(lakes, linewidth=0.2, zorder=1) ax.add_feature(bodr, edgecolor='k', zorder=1, linewidth=0.5) #ax.add_feature(rivers, linewidth=0.5,zorder=1) if plotcontour: # Add the 500 hPa geopotential height contour levels = np.arange(100., 2000., 10.) contours = plt.contour(to_np(lons), to_np(lats), to_np(ht_500), levels=levels, colors="forestgreen", linewidths=1, transform=ccrs.PlateCarree(), zorder=3) plt.clabel(contours, inline=1, fontsize=10, fmt="%i") if plotcontourf: try: with open(home + '/kode/colormaps/SINTEF1.json') as f: json_data = json.load(f) SINTEF1 = np.reshape(json_data[0]['RGBPoints'], (-1, 4)) cmap = ListedColormap(fill_colormap(SINTEF1)) except: print( 'SINTEF1 colormap not found (can be found at https://github.com/Zetison/colormaps.git)' ) cmap = get_cmap("rainbow") # Add the wind speed contours levels = np.linspace(20, 120, 101) wspd_contours = plt.contourf(to_np(lons), to_np(lats), to_np(wspd_500), levels=levels, cmap=cmap, alpha=0.7, antialiased=True, transform=ccrs.PlateCarree(), zorder=2) cbar_wspd = plt.colorbar(wspd_contours, ax=ax, orientation="horizontal", pad=.05, shrink=0.5, aspect=30, ticks=range(10, 110, 10)) cbar_wspd.ax.set_xlabel('Wind speeds [' + w_unitStr + '] at 500 mbar height') # Add the 500 hPa wind barbs, only plotting every nthb data point. nthb = 10 if plotbarbs: plt.barbs(to_np(lons[::nthb, ::nthb]), to_np(lats[::nthb, ::nthb]), to_np(u_500[::nthb, ::nthb]), to_np(v_500[::nthb, ::nthb]), transform=ccrs.PlateCarree(), length=6, zorder=3) track = sgeom.LineString( zip(df_obs['Longitude'].to_numpy(), df_obs['Latitude'].to_numpy())) fullFlightPath = ax.add_geometries([track], ccrs.PlateCarree(), facecolor='none', zorder=4, edgecolor='red', linewidth=2, label='Flight path') track = sgeom.LineString(zip(lon_e, lat_e)) flightPath = ax.add_geometries([track], ccrs.PlateCarree(), facecolor='none', zorder=4, linestyle=':', edgecolor='green', linewidth=2, label='Extracted flight path') #plt.legend(handles=[fullFlightPath]) #blue_line = mlines.Line2D([], [], color='red',linestyle='--', label='Flight path',linewidth=2) #plt.legend(handles=[blue_line]) # Set the map bounds ax.set_xlim(cartopy_xlim(ht_500)) ax.set_ylim(cartopy_ylim(ht_500)) #ax.gridlines(draw_labels=True) ax.gridlines() startdate = pd.to_datetime(str( time_e[0])).strftime("%Y-%m-%d %H:%M:%S") plt.title('Flight ' + sourceid + ', with visualization of WRF simulation (' + startdate + ') at 500 mbar Height (' + z_unitStr + '), Wind Speed (' + w_unitStr + '), Barbs (' + w_unitStr + ')') # Plot domain boundaries infile_d01 = wrffolder + '/wrfout_d01.nc' cart_proj, xlim_d01, ylim_d01 = get_plot_element(infile_d01) infile_d02 = wrffolder + '/wrfout_d02.nc' _, xlim_d02, ylim_d02 = get_plot_element(infile_d02) infile_d03 = wrffolder + '/wrfout_d03.nc' _, xlim_d03, ylim_d03 = get_plot_element(infile_d03) infile_d04 = wrffolder + '/wrfout_d04.nc' _, xlim_d04, ylim_d04 = get_plot_element(infile_d04) # d01 ax.set_xlim([ xlim_d01[0] - (xlim_d01[1] - xlim_d01[0]) / 15, xlim_d01[1] + (xlim_d01[1] - xlim_d01[0]) / 15 ]) ax.set_ylim([ ylim_d01[0] - (ylim_d01[1] - ylim_d01[0]) / 15, ylim_d01[1] + (ylim_d01[1] - ylim_d01[0]) / 15 ]) # d01 box textSize = 10 colors = ['blue', 'orange', 'brown', 'deepskyblue'] linewidth = 1 txtscale = 0.003 ax.add_patch( mpl.patches.Rectangle((xlim_d01[0], ylim_d01[0]), xlim_d01[1] - xlim_d01[0], ylim_d01[1] - ylim_d01[0], fill=None, lw=linewidth, edgecolor=colors[0], zorder=10)) ax.text(xlim_d01[0], ylim_d01[0] + (ylim_d01[1] - ylim_d01[0]) * (1 + txtscale), 'd01', size=textSize, color=colors[0], zorder=10) # d02 box ax.add_patch( mpl.patches.Rectangle((xlim_d02[0], ylim_d02[0]), xlim_d02[1] - xlim_d02[0], ylim_d02[1] - ylim_d02[0], fill=None, lw=linewidth, edgecolor=colors[1], zorder=10)) ax.text(xlim_d02[0], ylim_d02[0] + (ylim_d02[1] - ylim_d02[0]) * (1 + txtscale * 3), 'd02', size=textSize, color=colors[1], zorder=10) # d03 box ax.add_patch( mpl.patches.Rectangle((xlim_d03[0], ylim_d03[0]), xlim_d03[1] - xlim_d03[0], ylim_d03[1] - ylim_d03[0], fill=None, lw=linewidth, edgecolor=colors[2], zorder=10)) ax.text(xlim_d03[0], ylim_d03[0] + (ylim_d03[1] - ylim_d03[0]) * (1 + txtscale * 3**2), 'd03', size=textSize, color=colors[2], zorder=10) # d04 box ax.add_patch( mpl.patches.Rectangle((xlim_d04[0], ylim_d04[0]), xlim_d04[1] - xlim_d04[0], ylim_d04[1] - ylim_d04[0], fill=None, lw=linewidth, edgecolor=colors[3], zorder=10)) ax.text(xlim_d04[0], ylim_d04[0] + (ylim_d04[1] - ylim_d04[0]) * (1 + txtscale * 3**3), 'd04', size=textSize, color=colors[3], zorder=10) plt.show() fig.savefig(folder + '/' + sourceid + '_map.png', dpi=400)
def plot_all(dom): t1dom = time.perf_counter() print(('Working on '+dom)) # Map corners for each domain llcrnrlon = np.min(lon) llcrnrlat = np.min(lat) urcrnrlon = np.max(lon) urcrnrlat = np.max(lat) lat_0 = Lat0 lon_0 = Lon0 extent=[llcrnrlon,urcrnrlon,llcrnrlat-1,urcrnrlat] # create figure and axes instances fig = plt.figure(figsize=(10,10)) ax1 = fig.add_axes([0.1,0.1,0.8,0.8]) # Define where Cartopy Maps are located cartopy.config['data_dir'] = CARTOPY_DIR os.environ["CARTOPY_USER_BACKGROUNDS"]=CARTOPY_DIR+'/raster_files' back_res='50m' back_img='off' # set up the map background with cartopy myproj=ccrs.LambertConformal(central_longitude=lon_0, central_latitude=lat_0, false_easting=0.0, false_northing=0.0, secant_latitudes=None, standard_parallels=None, globe=None) ax = plt.axes(projection=myproj) ax.set_extent(extent) fline_wd = 0.5 # line width falpha = 0.3 # transparency # natural_earth # land=cfeature.NaturalEarthFeature('physical','land',back_res, # edgecolor='face',facecolor=cfeature.COLORS['land'], # alpha=falpha) lakes=cfeature.NaturalEarthFeature('physical','lakes',back_res, edgecolor='blue',facecolor='none', linewidth=fline_wd,alpha=falpha) coastline=cfeature.NaturalEarthFeature('physical','coastline', back_res,edgecolor='blue',facecolor='none', linewidth=fline_wd,alpha=falpha) states=cfeature.NaturalEarthFeature('cultural','admin_1_states_provinces', back_res,edgecolor='black',facecolor='none', linewidth=fline_wd,linestyle=':',alpha=falpha) borders=cfeature.NaturalEarthFeature('cultural','admin_0_countries', back_res,edgecolor='red',facecolor='none', linewidth=fline_wd,alpha=falpha) # high-resolution background images if back_img=='on': ax.background_img(name='NE', resolution='high') # ax.add_feature(land) ax.add_feature(lakes) ax.add_feature(states) ax.add_feature(borders) ax.add_feature(coastline) # All lat lons are earth relative, so setup the associated projection correct for that data transform = ccrs.PlateCarree() # Map/figure has been set up here, save axes instances for use again later keep_ax_lst = ax.get_children()[:] ################################ # Plot SLP ################################ t1 = time.perf_counter() print(('Working on slp for '+dom)) units = 'mb' clevs = [976,980,984,988,992,996,1000,1004,1008,1012,1016,1020,1024,1028,1032,1036,1040,1044,1048,1052] clevsdif = [-12,-10,-8,-6,-4,-2,0,2,4,6,8,10,12] cm = plt.cm.Spectral_r norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs1_a = plt.pcolormesh(lon_shift,lat_shift,slp,transform=transform,cmap=cm,norm=norm) cbar1 = plt.colorbar(cs1_a,orientation='horizontal',pad=0.05,shrink=0.6,extend='both') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) cs1_b = plt.contour(lon_shift,lat_shift,slpsmooth,np.arange(940,1060,4),colors='black',linewidths=1.25,transform=transform) plt.clabel(cs1_b,np.arange(940,1060,4),inline=1,fmt='%d',fontsize=8) ax.text(.5,1.03,'FV3-LAM SLP ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('slp_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot slp for: '+dom) % t3) ################################# # Plot 2-m T ################################# t1 = time.perf_counter() print(('Working on t2m for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = '\xb0''F' clevs = np.linspace(-16,134,51) cm = cmap_t2m() norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,tmp2m,transform=transform,cmap=cm,norm=norm) cs_1.cmap.set_under('white') cs_1.cmap.set_over('white') cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,ticks=[-16,-4,8,20,32,44,56,68,80,92,104,116,128],extend='both') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) ax.text(.5,1.03,'FV3-LAM 2-m Temperature ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('2mt_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot 2mt for: '+dom) % t3) ################################# # Plot 2-m Dew Point ################################# t1 = time.perf_counter() print(('Working on 2mdew for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = '\xb0''F' clevs = np.linspace(-5,80,35) cm = cmap_q2m() norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,dew2m,transform=transform,cmap=cm,norm=norm) cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,extend='both') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) ax.text(.5,1.03,'FV3-LAM 2-m Dew Point Temperature ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('2mdew_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot 2mdew for: '+dom) % t3) ################################# # Plot 10-m WSPD ################################# t1 = time.perf_counter() print(('Working on 10mwspd for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = 'kts' skip = 50 barblength = 4 clevs = [5,10,15,20,25,30,35,40,45,50,55,60] colorlist = ['turquoise','dodgerblue','blue','#FFF68F','#E3CF57','peru','brown','crimson','red','fuchsia','DarkViolet'] cm = matplotlib.colors.ListedColormap(colorlist) norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,wspd10m,transform=transform,cmap=cm,vmin=5,norm=norm) cs_1.cmap.set_under('white',alpha=0.) cs_1.cmap.set_over('black') cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,ticks=clevs,extend='max') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) plt.barbs(lon_shift[::skip,::skip],lat_shift[::skip,::skip],uwind[::skip,::skip],vwind[::skip,::skip],length=barblength,linewidth=0.5,color='black',transform=transform) ax.text(.5,1.03,'FV3-LAM 10-m Winds ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('10mwind_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot 10mwspd for: '+dom) % t3) ################################# # Plot Surface-Based CAPE/CIN ################################# t1 = time.perf_counter() print(('Working on surface-based CAPE/CIN for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = 'J/kg' clevs = [100,250,500,1000,1500,2000,2500,3000,3500,4000,4500,5000] clevs2 = [-2000,-500,-250,-100,-25] colorlist = ['lightblue','blue','dodgerblue','cyan','mediumspringgreen','#FAFAD2','#EEEE00','#EEC900','darkorange','crimson','darkred'] cm = matplotlib.colors.ListedColormap(colorlist) norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,cape,transform=transform,cmap=cm,vmin=100,norm=norm) cs_1.cmap.set_under('white',alpha=0.) cs_1.cmap.set_over('darkviolet') cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,ticks=clevs,extend='max') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) cs_1b = plt.contourf(lon_shift,lat_shift,cin,clevs2,colors='none',hatches=['**','++','////','..'],transform=transform) ax.text(.5,1.05,'FV3-LAM Surface-Based CAPE (shaded) and CIN (hatched) ('+units+') \n <-500 (*), -500<-250 (+), -250<-100 (/), -100<-25 (.) \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('sfcape_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot surface-based CAPE/CIN for: '+dom) % t3) ################################# # Plot 500 mb HGT/WIND/VORT ################################# # t1 = time.perf_counter() # print(('Working on 500 mb Hgt/Wind/Vort for '+dom)) # # # Clear off old plottables but keep all the map info # cbar1.remove() # clear_plotables(ax,keep_ax_lst,fig) # # units = 'x10${^5}$ s${^{-1}}$' # skip = 70 # barblength = 4 # # vortlevs = [16,20,24,28,32,36,40] # colorlist = ['yellow','gold','goldenrod','orange','orangered','red'] # cm = matplotlib.colors.ListedColormap(colorlist) # norm = matplotlib.colors.BoundaryNorm(vortlevs, cm.N) # # cs1_a = plt.pcolormesh(lon_shift,lat_shift,vort500,transform=transform,cmap=cm,norm=norm) # cs1_a.cmap.set_under('white') # cs1_a.cmap.set_over('darkred') # cbar1 = plt.colorbar(cs1_a,orientation='horizontal',pad=0.05,shrink=0.6,ticks=vortlevs,extend='both') # cbar1.set_label(units,fontsize=8) # cbar1.ax.tick_params(labelsize=8) # plt.barbs(lon_shift[::skip,::skip],lat_shift[::skip,::skip],u500[::skip,::skip],v500[::skip,::skip],length=barblength,linewidth=0.5,color='steelblue',transform=transform) # cs1_b = plt.contour(lon_shift,lat_shift,z500,np.arange(486,600,6),colors='black',linewidths=1,transform=transform) # plt.clabel(cs1_b,np.arange(486,600,6),inline_spacing=1,fmt='%d',fontsize=8) # ax.text(.5,1.03,'FV3-LAM 500 mb Heights (dam), Winds (kts), and $\zeta$ ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) # # compress_and_save('500_'+dom+'_f'+fhour+'.png') # t2 = time.perf_counter() # t3 = round(t2-t1, 3) # print(('%.3f seconds to plot 500 mb Hgt/Wind/Vort for: '+dom) % t3) ################################# # Plot 250 mb WIND ################################# t1 = time.perf_counter() print(('Working on 250 mb WIND for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = 'kts' skip = 70 barblength = 4 clevs = [50,60,70,80,90,100,110,120,130,140,150] colorlist = ['turquoise','deepskyblue','dodgerblue','#1874CD','blue','beige','khaki','peru','brown','crimson'] cm = matplotlib.colors.ListedColormap(colorlist) norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,wspd250,transform=transform,cmap=cm,vmin=50,norm=norm) cs_1.cmap.set_under('white',alpha=0.) cs_1.cmap.set_over('red') cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,ticks=clevs,extend='max') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) plt.barbs(lon_shift[::skip,::skip],lat_shift[::skip,::skip],u250[::skip,::skip],v250[::skip,::skip],length=barblength,linewidth=0.5,color='black',transform=transform) ax.text(.5,1.03,'FV3-LAM 250 mb Winds ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('250wind_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot 250 mb WIND for: '+dom) % t3) ################################# # Plot Total QPF ################################# if (fhr > 0): # Do not make total QPF plot for forecast hour 0 t1 = time.perf_counter() print(('Working on total qpf for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = 'in' clevs = [0.01,0.1,0.25,0.5,0.75,1,1.25,1.5,1.75,2,2.5,3,4,5,7,10,15,20] clevsdif = [-3,-2.5,-2,-1.5,-1,-0.5,0,0.5,1,1.5,2,2.5,3] colorlist = ['chartreuse','limegreen','green','blue','dodgerblue','deepskyblue','cyan','mediumpurple','mediumorchid','darkmagenta','darkred','crimson','orangered','darkorange','goldenrod','gold','yellow'] cm = matplotlib.colors.ListedColormap(colorlist) norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,qpf,transform=transform,cmap=cm,vmin=0.01,norm=norm) cs_1.cmap.set_under('white',alpha=0.) cs_1.cmap.set_over('pink') cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,ticks=clevs,extend='max') cbar1.set_label(units,fontsize=8) cbar1.ax.set_xticklabels(clevs) cbar1.ax.tick_params(labelsize=8) ax.text(.5,1.03,'FV3-LAM '+fhour+'-hr Accumulated Precipitation ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('qpf_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot total qpf for: '+dom) % t3) ################################# # Plot composite reflectivity ################################# t1 = time.perf_counter() print(('Working on composite reflectivity for '+dom)) # Clear off old plottables but keep all the map info cbar1.remove() clear_plotables(ax,keep_ax_lst,fig) units = 'dBZ' clevs = np.linspace(5,70,14) clevsdif = [20,1000] colorlist = ['turquoise','dodgerblue','mediumblue','lime','limegreen','green','#EEEE00','#EEC900','darkorange','red','firebrick','darkred','fuchsia'] cm = matplotlib.colors.ListedColormap(colorlist) norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) cs_1 = plt.pcolormesh(lon_shift,lat_shift,refc,transform=transform,cmap=cm,vmin=5,norm=norm) cs_1.cmap.set_under('white',alpha=0.) cs_1.cmap.set_over('black') cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,ticks=clevs,extend='max') cbar1.set_label(units,fontsize=8) cbar1.ax.tick_params(labelsize=8) ax.text(.5,1.03,'FV3-LAM Composite Reflectivity ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) compress_and_save('refc_'+dom+'_f'+fhour+'.png') t2 = time.perf_counter() t3 = round(t2-t1, 3) print(('%.3f seconds to plot composite reflectivity for: '+dom) % t3) ################################# # Plot Max/Min Hourly 2-5 km UH ################################# # if (fhr > 0): # Do not make max/min hourly 2-5 km UH plot for forecast hour 0 # t1 = time.perf_counter() # print(('Working on Max/Min Hourly 2-5 km UH for '+dom)) # # # Clear off old plottables but keep all the map info # cbar1.remove() # clear_plotables(ax,keep_ax_lst,fig) # # units = 'm${^2}$ s$^{-2}$' # clevs = [-150,-100,-75,-50,-25,-10,0,10,25,50,75,100,150,200,250,300] ## alternative colormap for just max UH if you don't want to plot the min UH too ## colorlist = ['white','skyblue','mediumblue','green','orchid','firebrick','#EEC900','DarkViolet'] # colorlist = ['blue','#1874CD','dodgerblue','deepskyblue','turquoise','#E5E5E5','#E5E5E5','#EEEE00','#EEC900','darkorange','orangered','red','firebrick','mediumvioletred','darkviolet'] # cm = matplotlib.colors.ListedColormap(colorlist) # norm = matplotlib.colors.BoundaryNorm(clevs, cm.N) # # cs_1 = plt.pcolormesh(lon_shift,lat_shift,uh25,transform=transform,cmap=cm,norm=norm) # cs_1.cmap.set_under('darkblue') # cs_1.cmap.set_over('black') # cbar1 = plt.colorbar(cs_1,orientation='horizontal',pad=0.05,shrink=0.6,extend='both') # cbar1.set_label(units,fontsize=8) # cbar1.ax.tick_params(labelsize=8) # ax.text(.5,1.03,'FV3-LAM 1-h Max/Min 2-5 km Updraft Helicity ('+units+') \n initialized: '+itime+' valid: '+vtime + ' (f'+fhour+')',horizontalalignment='center',fontsize=8,transform=ax.transAxes,bbox=dict(facecolor='white',alpha=0.85,boxstyle='square,pad=0.2')) # # compress_and_save('uh25_'+dom+'_f'+fhour+'.png') # t2 = time.perf_counter() # t3 = round(t2-t1, 3) # print(('%.3f seconds to plot Max/Min Hourly 2-5 km UH for: '+dom) % t3) # ###################################################### t3dom = round(t2-t1dom, 3) print(("%.3f seconds to plot all variables for: "+dom) % t3dom) plt.clf()
plt.subplot(1,3,1) plt.title('Potential Temperature') plt.plot(profile['TH'],profile['PH'],linewidth=2,color='red') plt.xlabel('Potential Temperature (K)') plt.ylabel('Geopotential Height (m)') plt.subplot(1,3,2) plt.title('Mixing Ratio') plt.plot(profile['QV'],profile['PH'],linewidth=2,color='green') plt.xlabel('Mixing Ratio (kg/kg)') plt.ylabel('Geopotential Height (m)') plt.subplot(1,3,3) plt.title('Wind') plt.plot(profile['UU'],profile['PH'],linewidth=2, color='blue', label="U vector") plt.ylabel('Geopotential Height (m)') plt.plot(profile['VV'],profile['PH'],linewidth=2, color='orange', label="V vector") plt.xlabel('V wind (m/s)') plt.ylabel('Geopotential Height (m)') plt.axvline(0,color='red') plt.barbs(np.zeros(len(profile['PH'])),profile['PH'],profile['UU'],profile['VV']) plt.xlabel('Wind Vector (m/s) Half=5, Full=10, Flag=50') plt.ylabel('Geopotential Height (m)') plt.legend(loc='center left', bbox_to_anchor=(1, 0.5),prop={'size':10}) plt.show()
#>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #### Do the same for wind barbs # plot on a graph fig = plt.figure(4) ax = fig.add_subplot(111) file_start_date = datetime.strptime(f00[station][date_start_index],'%Y-%m-%d %H:%M') MW_u, MW_v = wind_spddir_to_uv(a['wind speed'],a['wind direction']) # If u or v is nan, then set to zero. We got a nan origianlly # becuase no direction was reported. Speed is zero in these instances. MW_u[np.isnan(MW_u)]=0 MW_v[np.isnan(MW_v)]=0 idx = mpl.dates.date2num(a['datetimes']) plt.barbs(idx,np.ones_like(MW_u),MW_u,MW_v, barb_increments=dict(half=2.5, full=5, flag=25),length=5.25) position = [2,3,4,5,6] for i in range(0,len(anal_hours)): file_start_date = datetime.strptime(f00[station][date_start_index+anal_hours[i]],'%Y-%m-%d %H:%M') Aug5_00UTC_line_U = np.array([]) Aug5_00UTC_line_V = np.array([]) Aug5_00UTC_line_U = np.append(Aug5_00UTC_line_U,f00['u'][date_start_index+anal_hours[i]]) Aug5_00UTC_line_U = np.append(Aug5_00UTC_line_U,f01['u'][date_start_index+1+anal_hours[i]]) Aug5_00UTC_line_U = np.append(Aug5_00UTC_line_U,f02['u'][date_start_index+2+anal_hours[i]]) Aug5_00UTC_line_U = np.append(Aug5_00UTC_line_U,f03['u'][date_start_index+3+anal_hours[i]]) Aug5_00UTC_line_U = np.append(Aug5_00UTC_line_U,f04['u'][date_start_index+4+anal_hours[i]]) Aug5_00UTC_line_U = np.append(Aug5_00UTC_line_U,f05['u'][date_start_index+5+anal_hours[i]])
################################# # Make figure # font sizes cb_fs = 18 lb_fs = 16 tk_fs = 13 bx_fs = 19 fig = plt.figure() ax = plt.subplot(111) plt.plot(ws_sod_avg, z_sod, lw=1.8, zorder=10) plt.plot(ws_wrf_avg[2:-1], z_wrf[2:-1], lw=1.8, zorder=10) plt.barbs(ws_sod_avg, z_sod, u_sod_avg*1.94, v_sod_avg*1.94, zorder=11) plt.barbs(ws_wrf_avg[2:-1], z_wrf[2:-1], u_wrf_avg[2:-1]*1.94, v_wrf_avg[2:-1]*1.94, zorder=11) ax.set_xlabel('Wind Speed (m s$^{-1}$)', fontsize=lb_fs) ax.set_ylabel(r'z (m $AGL$)', fontsize=lb_fs) plt.tick_params(axis='both', which='major', labelsize=tk_fs) plt.grid() plt.xlim(1,9) plt.ylim(0,160) plt.text(0.03, 0.91, ' Monthly mean, Power deficit > '+str(P)+' MW', ha='left', fontsize=bx_fs-4, transform=ax.transAxes, bbox=dict(facecolor='w', edgecolor='none', alpha=0.7)) plt.text(0.03, 0.8, 'Sodar', color='b', ha='left', fontsize=bx_fs, transform=ax.transAxes, bbox=dict(facecolor='w', edgecolor='none', alpha=0.7)) plt.text(0.03, 0.7, 'WRF', color='g', ha='left', fontsize=bx_fs, transform=ax.transAxes, bbox=dict(facecolor='w', edgecolor='none', alpha=0.7))
def plot_sounding(axes, z, th, p, qv, u = None, v = None): """Plot sounding data This plots temperature, dewpoint and wind data on a Skew-T/Log-P plot. This will also plot derived values such as wetbulb temperature and label the surface based LCL, LFC and EL. :parameter z: height values (1D array) :parameter th: potential temperature at z heights (1D array) :parameter p: pressure at z heights (1D array) :parameter qv: water vapor mixing ratio at z heights (1D array) :parameter u: U component of wind at z heights (1D array) :parameter v: V component of wind at z heights (1D array) :paramter axes: The axes instance to draw on """ # calculate Temperature and dewpoint T = met.T(th,p) - met.T00 # T (C) Td = met.Td(p, qv) - met.T00 # Td (C) # calculate wetbulb temperature Twb = np.empty(len(z), np.float32) # Twb (C) for zlvl in range(len(z)): Twb[zlvl] = met.Twb(z, p, th, qv, z[zlvl]) # Get surface parcel CAPE and temperature / height profiles pcl = met.CAPE(z, p, T+met.T00, qv, 1) # CAPE T_parcel = pcl['t_p'] - met.T00 # parcel T (C) T_vparcel = pcl['tv_p'] - met.T00 # parcel Tv (C) T_venv = met.T(pcl['thv_env'], pcl['pp']) - met.T00 # Env Tv (C) # plot Temperature, dewpoint, wetbulb and lifted surface parcel profiles on skew axes axes.semilogy(T + skew(p), p, basey=math.e, color=linecolor_T , linewidth = linewidth_T) axes.semilogy(Td + skew(p), p, basey=math.e, color=linecolor_Td, linewidth = linewidth_Td) axes.semilogy(T_parcel + skew(pcl['pp']), pcl['pp'], basey=math.e, color=linecolor_Parcel_T, linewidth=linewidth_Parcel_T) axes.semilogy(Twb + skew(p), p, basey=math.e, color=linecolor_Twb, linewidth=linewidth_Twb) # plot virtual temperature of environment and lifted parcel axes.semilogy(T_venv + skew(pcl['pp']), pcl['pp'], basey=math.e, color=linecolor_Tve, linewidth=linewidth_Tve, linestyle=linestyle_Tve) axes.semilogy(T_vparcel + skew(pcl['pp']), pcl['pp'], basey=math.e, color=linecolor_Tvp, linewidth=linewidth_Tvp, linestyle=linestyle_Tvp) # Add labels for levels based on surface parcel #debug print(pcl['lfcprs'], pcl['lclprs'], pcl['elprs'], pcl['ptops']) if (pcl['lfcprs'] > 0): label_m(Tmax-.5, pcl['lfcprs'], '--LFC', axes) if (pcl['lclprs'] > 0): label_m(Tmax-.5, pcl['lclprs'], '--LCL', axes) if (pcl['elprs'] > 0): label_m(Tmax-.5, pcl['elprs'], '--EL', axes) if (pcl['ptops'] > 0): label_m(Tmax-.5, pcl['ptops'], '--TOPS', axes) # plot labels for std heights for plvl in plevs_std: zlvl = pymeteo.interp.interp_height(z,p,plvl) label_m(Tmin-.5,plvl, str(int(zlvl)), axes) # plot wind barbs on left side of plot. move this? right side? if (u is not None and v is not None): #draw_wind_line(axes) for i in np.arange(0,len(z),2): if (p[i] > pt_plot): plt.barbs(Tmin+4,p[i],u[i],v[i], length=5, linewidth=.5)
cbar_loc = plt.colorbar(shrink=.8,pad=.01,ticks= np.arange(-8,8.1,1),extend='both') cbar_loc.ax.set_ylabel('Wind Speed (m/s)') """ # contourf plt.contourf(x,y,masked_V10,cmap='BrBG',levels=np.arange(-8,8.1,.5),extend='both') cbar_loc = plt.colorbar(shrink=.8,pad=.01,ticks= np.arange(-8,8.1,1)) cbar_loc.ax.set_ylabel('10-m V Wind (m/s)') plt.contour(x,y,landmask, [0,1], linewidths=1, colors="b") #plt.contour(x,y,HGT) #plt.contourf(x,y,HGT,cmap=cmapgrey) # transparent greay if plotted on top plt.barbs(x[::3,::3],y[::3,::3],masked_U10[::3,::3],masked_V10[::3,::3], length=6, barb_increments=dict(half=1, full=2, flag=10), sizes=dict(emptybarb=.1)) plt.contour(x,y,masked_Q2,linewidths=2,levels=[1,2,3,4,5,6,7,8,9,10],cmap='PiYG') cbar_WV = plt.colorbar(orientation='horizontal',shrink=.8,pad=.01,) cbar_WV.ax.set_xlabel('2-m Water Vapor (g/kg)') xs,ys = m(-111.97,40.78) #buffr sounding coordinates #plt.scatter(xs,ys, s=70, c='w') plt.title(time_str+'\n'+time_str_local, bbox=dict(facecolor='white', alpha=0.65),\ x=0.5,y=1.05,weight = 'demibold',style='oblique', \ stretch='normal', family='sans-serif') plt.savefig(out_dir+'contour_V10_barbs_'+time_file+'.png',bbox_inches="tight")
# # # Create figure and axes # fig = plt.figure(1) # # fig.clf() # ax = fig.add_subplot(1, 1, 1) # # c2 = np.linspace(10, 40, 7) # # c = np.linspace(0, 10, 1000) # print len(c) # print len(x),len(y) # # ax.scatter(x, y, c=c, cmap=cmap) # # plt.show() import matplotlib as mpl import matplotlib.pyplot as plt from numpy import arange,meshgrid,sqrt u,v = arange(-50,51,10),arange(-50,51,10) u,v = meshgrid(u,v) x,y = u,v C = sqrt(u**2 + v**2) cmap=plt.cm.jet bounds = [10, 20, 40, 60] norm = mpl.colors.BoundaryNorm(bounds, cmap.N) img=plt.barbs(x,y,u,v,C,cmap=cmap,norm=norm) # plt.colorbar(img, cmap=cmap, norm=norm, boundaries=bounds, ticks=bounds) plt.show()
# Slice interval for barbs slice_interval = 4 # Slicer index for smoother barbs plot skip = (slice(None, None, slice_interval), slice(None, None, slice_interval)) plt.figure() # barbs = plt.barbs(X1, X2, U, V) barbs = plt.barbs( X1[skip], X2[skip], U[skip], V[skip], vels[skip], pivot='tip', # color='green', cmap=plt.cm.jet, barb_increments={ 'half': 10, 'full': 20, 'flag': 50 }) plt.colorbar(barbs) plt.title("Van der pol Phase Portrait") plt.xlabel("x") plt.ylabel("y") plt.xticks() plt.yticks() plt.axis([-l, l, -l, l]) plt.grid() plt.show()
def plot_upper_lv_winds(ncFile, targetDir, levels, windScaleFactor=50, withHeights=True): logger = PyPostTools.pyPostLogger() st, fh, fh_int = getTimeObjects(ncFile) for level in levels: fig, ax, X, Y = prepare_plot_object(ncFile) titleAdd = "" u = ncFile["U_" + str(level)] v = ncFile["V_" + str(level)] uKT = Conversions.ms_to_kts(u) vKT = Conversions.ms_to_kts(v) spd = np.sqrt(uKT * uKT + vKT * vKT) smooth_wnd = gaussian_filter(to_np(spd), sigma=3) if level >= 850: clevs = np.arange(10, 120, 5) elif (level >= 500 and level < 850): clevs = np.arange(25, 180, 5) else: clevs = np.arange(50, 230, 5) contours = plt.contourf(X, Y, smooth_wnd, clevs, cmap=get_cmap('rainbow'), transform=ccrs.PlateCarree()) cbar = plt.colorbar(ax=ax, orientation="horizontal", pad=.05) cbar.set_label("Wind Speed (Kts)") plt.barbs(to_np(X[::windScaleFactor, ::windScaleFactor]), to_np(Y[::windScaleFactor, ::windScaleFactor]), to_np(uKT[::windScaleFactor, ::windScaleFactor]), to_np(vKT[::windScaleFactor, ::windScaleFactor]), transform=ccrs.PlateCarree(), length=6) if (withHeights == True): z = ncFile["GEOHT_" + str(level)] zDM = z / 10 smooth_lines = gaussian_filter(to_np(zDM), sigma=3) if (level <= 200): cont_levels = np.arange(800., 1600., 6.) elif (level <= 400): cont_levels = np.arange(600., 1200., 6.) elif (level <= 600): cont_levels = np.arange(200., 800., 6.) elif (level <= 800): cont_levels = np.arange(100., 600., 6.) else: cont_levels = np.arange(0., 400., 6.) contours = plt.contour(X, Y, smooth_lines, levels=cont_levels, colors="black", transform=ccrs.PlateCarree()) plt.clabel(contours, inline=1, fontsize=10, fmt="%i") titleAdd += ", Geopotential Height (dm)" plt.title(str(level) + "mb Winds (kts)" + titleAdd) plt.text(0.02, -0.02, "Forecast Time: " + fh.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.text(0.7, -0.02, "Initialized: " + st.strftime("%Y-%m-%d %H:%M UTC"), ha='left', va='center', transform=ax.transAxes) plt.subplots_adjust(bottom=0.1) plt.savefig(targetDir + "/" + str(level) + "winds_F" + str(fh_int)) plt.close(fig)