def map_lakepct(var, lon, lat, levels, title_str, clrmap, fig_name, alone=True, ax=False): # figure creation if alone: fig, ax = plt.subplots(1, 1, figsize=(13, 8), subplot_kw={'projection': ccrs.PlateCarree()}) ax.add_feature(ctp.feature.OCEAN, color='gainsboro') ax.coastlines(color='darkgrey') #ax.coastlines(color="grey") LON, LAT = mpu.infer_interval_breaks(lon, lat) # add the data to the map (more info on colormaps: https://matplotlib.org/users/colormaps.html) cmap, norm = mpu.from_levels_and_cmap(levels, clrmap) # do not show zeros var[var == 0] = np.nan cmap.set_over(cmap(0.99)) h = ax.pcolormesh(LON, LAT, var, cmap=cmap, norm=norm) # set the extent of the cartopy geoAxes to "global" ax.set_global() ax.set_title(title_str, pad=10, loc='right') # remove the frame ax.outline_patch.set_visible(False) # plot the colorbar cbar = mpu.colorbar(h, ax, orientation='horizontal', pad=0.1, extend='max') cbar.ax.set_xlabel('Natural lake area fraction [%]', size=16) cbar.set_ticks(np.arange(0, 110, 10)) # horizontal colorbar #cbar.ax.set_xticklabels(['Low', 'Medium', 'High']) # horizontal colorbar # if so, save the figure if fig_name != 0 and alone: plt.savefig(fig_name + '.jpeg', dpi=1000, bbox_inches='tight')
def plot_region_hc_map(var, region_props, lakes_path, indir_lakedata): # get region specific info from dictionary extent = region_props['extent'] continent_extent = region_props['continent_extent'] name = region_props['name'] name_str = region_props['name_str'] ax_location = region_props['ax_location'] levels = region_props['levels'] fig_size = region_props['fig_size'] cb_orientation = region_props['cb_orientation'] path_lakes = lakes_path + name + '.shp' # settings clb_label = 'Joule' title_str = name_str + ' heat content anomaly' fig_name = 'Heat_content_' + name cmap = 'YlOrBr' cmap, norm = mpu.from_levels_and_cmap(levels, cmap, extend='max') lon, lat = get_lonlat(indir_lakedata) LON, LAT = mpu.infer_interval_breaks(lon, lat) lakes = gpd.read_file(path_lakes) # plotting fig, ax = plt.subplots(1, 1, figsize=fig_size, subplot_kw={'projection': ccrs.PlateCarree()}) ax.add_feature(ctp.feature.OCEAN, color='gainsboro') ax.coastlines(color="grey") # add the data to the map (more info on colormaps: https://matplotlib.org/users/colormaps.html) h = ax.pcolormesh(LON, LAT, var, cmap=cmap, norm=norm) # load the lake shapefile lakes.plot(ax=ax, edgecolor='gray', facecolor='none') # set grid lines gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=0.5, color='gainsboro', alpha=0.5) gl.xlines = True gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.xlabels_bottom = None gl.ylabels_right = None # set extent (in right way) extent[1], extent[2] = extent[2], extent[1] ax.set_extent(extent) # create effect for map borders: effect = Stroke(linewidth=1.5, foreground='darkgray') # set effect for main ax ax.outline_patch.set_path_effects([effect]) # Create an inset GeoAxes showing the location of the lakes region #x0 y0 width height sub_ax = fig.add_axes(ax_location, projection=ccrs.PlateCarree()) sub_ax.set_extent(continent_extent) #lakes.plot(ax=sub_ax) sub_ax.outline_patch.set_path_effects([effect]) extent_box = sgeom.box(extent[0], extent[2], extent[1], extent[3]) sub_ax.add_geometries([extent_box], ccrs.PlateCarree(), facecolor='none', edgecolor='red', linewidth=2) # Add the land, coastlines and the extent of the inset axis sub_ax.add_feature(cfeature.LAND, edgecolor='gray') sub_ax.coastlines(color='gray') extent_box = sgeom.box(extent[0], extent[2], extent[1], extent[3]) sub_ax.add_geometries([extent_box], ccrs.PlateCarree(), facecolor='none', edgecolor='black', linewidth=2) # plot the colorbar cbar = mpu.colorbar(h, ax, extend='max', orientation=cb_orientation, pad=0.05) if cb_orientation == 'vertical': cbar.ax.set_ylabel(clb_label, size=16) elif cb_orientation == 'horizontal': cbar.ax.set_xlabel(clb_label, size=16) #ax.set_title(title_str, pad=10) plotdir = '/home/inne/documents/phd/data/processed/isimip_lakeheat/plots/' plt.savefig(plotdir + fig_name + '.png', dpi=500)
def plot_global_hc_map(name_str, var, lakes_path, indir_lakedata): # get region specific info from dictionary if name_str == 'global_absolute': levels = np.arange(-1e17, 1.1e17, 0.1e17) elif name_str == 'global': levels = np.arange(-1e19, 1.1e19, 0.1e19) cb_orientation = 'horizontal' path_lakes = lakes_path + name_str + '.shp' # settings clb_label = 'Joule' title_str = name_str + ' heat content anomaly' fig_name = 'Heat_content_' + name_str cmap = 'RdBu_r' #, 'YlOrBr' cmap, norm = mpu.from_levels_and_cmap(levels, cmap, extend='max') lon, lat = get_lonlat(indir_lakedata) LON, LAT = mpu.infer_interval_breaks(lon, lat) # plotting fig, ax = plt.subplots(1, 1, figsize=(13, 8), subplot_kw={'projection': ccrs.PlateCarree()}) ax.add_feature(ctp.feature.OCEAN, color='gainsboro') ax.coastlines(color="grey") # add the data to the map (more info on colormaps: https://matplotlib.org/users/colormaps.html) h = ax.pcolormesh(LON, LAT, var, cmap=cmap, norm=norm) # set grid lines gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=0.5, color='gainsboro', alpha=0.5) gl.xlines = True gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER gl.xlabels_bottom = None gl.ylabels_right = None effect = Stroke(linewidth=1.5, foreground='darkgray') # set effect for main ax ax.outline_patch.set_path_effects([effect]) # plot the colorbar cbar = mpu.colorbar(h, ax, extend='max', orientation=cb_orientation, pad=0.05) if cb_orientation == 'vertical': cbar.ax.set_ylabel(clb_label, size=16) elif cb_orientation == 'horizontal': cbar.ax.set_xlabel(clb_label, size=16) #ax.set_title(title_str, pad=10) plotdir = '/home/inne/documents/phd/data/processed/isimip_lakeheat/plots/' plt.savefig(plotdir + fig_name + '.png')
f, ax = plt.subplots(1, 1, subplot_kw=dict(projection=ccrs.Robinson())) h = data.plot.pcolormesh(ax=ax, transform=ccrs.PlateCarree(), vmin=-2, vmax=2, cmap="RdBu_r", add_colorbar=False, rasterized=True) ax.coastlines() ax.set_global() ax.set_title("") f.subplots_adjust(left=0.025, right=0.875, bottom=0.05, top=0.95) mpu.colorbar(h, ax, extend='both') #mpu.colorbar(h, ax, extend='max') plt.draw() plt.savefig(out_file, dpi=400, bbox_inches="tight") #calculate BGP/BGC ratio file_B17 = f'{in_dir}TSrec_{scen}_B17_{season}_850-2015sum.nc' file_D18 = f'{in_dir}TSrec_{scen}_D18_{season}_850-2015sum.nc' rec = (xr.open_dataset(file_B17).TSrec + xr.open_dataset(file_D18).TSrec) / 2. BGP = rec.sum(dim=["conversion"]) ratio = (BGP / ts_map.where(ts_map > 0.01)) * 100. #plot map of BGP/BGC ratio data = ratio
def horizontal_map(variable_name, date, start_hour, end_hour, pressure_level=False, subset=False, initiation=False, save=False, gif=False): '''This function plots the chosen variable for the analysis of the initiation environment on a horizontal (2D) map. Supported variables for plotting procedure are updraft, reflectivity, helicity, pw, cape, cin, ctt, temperature_surface, wind_shear, updraft_reflectivity, rh, omega, pvo, avo, theta_e, water_vapor, uv_wind and divergence.''' ### Predefine some variables ### # Get the list of all needed wrf files data_dir = '/scratch3/thomasl/work/data/casestudy_baden/' # Define save directory save_dir = '/scratch3/thomasl/work/retrospective_part' '/casestudy_baden/horizontal_maps/' # Change extent of plot subset_extent = [6.2, 9.4, 46.5, 48.5] # Set the location of the initiation of the thunderstorm initiation_location = CoordPair(lat=47.25, lon=7.85) # 2D variables: if variable_name == 'updraft': variable_name = 'W_UP_MAX' title_name = 'Maximum Z-Wind Updraft' colorbar_label = 'Max Z-Wind Updraft [$m$ $s^-$$^1$]' save_name = 'updraft' variable_min = 0 variable_max = 30 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'reflectivity': variable_name = 'REFD_MAX' title_name = 'Maximum Derived Radar Reflectivity' colorbar_label = 'Maximum Derived Radar Reflectivity [$dBZ$]' save_name = 'reflectivity' variable_min = 0 variable_max = 75 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'helicity': variable_name = 'UP_HELI_MAX' title_name = 'Maximum Updraft Helicity' colorbar_label = 'Maximum Updraft Helicity [$m^{2}$ $s^{-2}$]' save_name = 'helicity' variable_min = 0 variable_max = 140 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'pw': title_name = 'Precipitable Water' colorbar_label = 'Precipitable Water [$kg$ $m^{-2}$]' save_name = 'pw' variable_min = 0 variable_max = 50 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'cape': variable_name = 'cape_2d' title_name = 'CAPE' colorbar_label = 'Convective Available Potential Energy' '[$J$ $kg^{-1}$]' save_name = 'cape' variable_min = 0 variable_max = 3000 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'cin': variable_name = 'cape_2d' title_name = 'CIN' colorbar_label = 'Convective Inhibition [$J$ $kg^{-1}$]' save_name = 'cin' variable_min = 0 variable_max = 100 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'ctt': title_name = 'Cloud Top Temperature' colorbar_label = 'Cloud Top Temperature [$K$]' save_name = 'cct' variable_min = 210 variable_max = 300 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'temperature_surface': variable_name = 'T2' title_name = 'Temperature @ 2 m' colorbar_label = 'Temperature [$K$]' save_name = 'temperature_surface' variable_min = 285 variable_max = 305 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'wind_shear': variable_name = 'slp' title_name = 'SLP, Wind @ 850hPa, Wind @ 500hPa\n' 'and 500-850hPa Vertical Wind Shear' save_name = 'wind_shear' variable_min = 1000 variable_max = 1020 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) elif variable_name == 'updraft_reflectivity': variable_name = 'W_UP_MAX' title_name = 'Updraft and Reflectivity' colorbar_label = 'Max Z-Wind Updraft [$m$ $s^-$$^1$]' save_name = 'updraft_reflectivity' variable_min = 0 variable_max = 30 # Check if a certain pressure_level was defined. if pressure_level != False: sys.exit('The variable {} is a 2D variable. ' 'Definition of a pressure_level for ' 'plotting process is not required.'.format(variable_name)) # 3D variables: elif variable_name == 'rh': title_name = 'Relative Humidity' colorbar_label = 'Relative Humidity [$pct$]' save_name = 'rh' variable_min = 0 variable_max = 100 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'omega': title_name = 'Vertical Motion' colorbar_label = 'Omega [$Pa$ $s^-$$^1$]' save_name = 'omega' variable_min = -50 variable_max = 50 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'pvo': title_name = 'Potential Vorticity' colorbar_label = 'Potential Vorticity [$PVU$]' save_name = 'pvo' variable_min = -1 variable_max = 9 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'avo': title_name = 'Absolute Vorticity' colorbar_label = 'Absolute Vorticity [$10^{-5}$' '$s^{-1}$]' save_name = 'avo' variable_min = -250 variable_max = 250 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'theta_e': title_name = 'Theta-E' colorbar_label = 'Theta-E [$K$]' save_name = 'theta_e' variable_min = 315 variable_max = 335 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'water_vapor': variable_name = 'QVAPOR' title_name = 'Water Vapor Mixing Ratio' colorbar_label = 'Water Vapor Mixing Ratio [$g$ $kg^{-1}$]' save_name = 'water_vapor' variable_min = 5 variable_max = 15 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'uv_wind': variable_name = 'wspd_wdir' title_name = 'Wind Speed and Direction' colorbar_label = 'Wind Speed [$m$ $s^{-1}$]' save_name = 'uv_wind' variable_min = 0 variable_max = 10 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) elif variable_name == 'divergence': variable_name = 'ua' title_name = 'Horizontal Wind Divergence' colorbar_label = 'Divergence [$10^{-6}$ $s^{-1}$]' save_name = 'divergence' variable_min = -2.5 variable_max = 2.5 # Check if a certain pressure_level was defined. if pressure_level == False: sys.exit('The variable {} is a 3D variable. ' 'Definition of a pressure_level for ' 'plotting process is required.'.format(variable_name)) # Make a list of all wrf files in data directory wrflist = list() for (dirpath, dirnames, filenames) in os.walk(data_dir): wrflist += [os.path.join(dirpath, file) for file in filenames] ### Plotting Iteration ### # Iterate over a list of hourly timesteps time = list() for i in range(start_hour, end_hour): time = str(i).zfill(2) # Iterate over all 5 minutes steps of hour for j in range(0, 60, 5): minutes = str(j).zfill(2) # Load the netCDF files out of the wrflist ncfile = [Dataset(x) for x in wrflist if x.endswith('{}_{}:{}:00'.format(date, time, minutes))] # Load variable(s) if title_name == 'CAPE': variable = getvar(ncfile, variable_name)[0,:] elif title_name == 'CIN': variable = getvar(ncfile, variable_name)[1,:] elif variable_name == 'ctt': variable = getvar(ncfile, variable_name, units='K') elif variable_name == 'wspd_wdir': variable = getvar(ncfile, variable_name)[0,:] elif variable_name == 'QVAPOR': variable = getvar(ncfile, variable_name)*1000 # convert to g/kg else: variable = getvar(ncfile, variable_name) if variable_name == 'slp': slp = variable.squeeze() ua = getvar(ncfile, 'ua') va = getvar(ncfile, 'va') p = getvar(ncfile, 'pressure') u_wind850 = interplevel(ua, p, 850) v_wind850 = interplevel(va, p, 850) u_wind850 = u_wind850.squeeze() v_wind850 = v_wind850.squeeze() u_wind500 = interplevel(ua, p, 500) v_wind500 = interplevel(va, p, 500) u_wind500 = u_wind500.squeeze() v_wind500 = v_wind500.squeeze() slp = ndimage.gaussian_filter(slp, sigma=3, order=0) # Interpolating 3d data to a horizontal pressure level if pressure_level != False: p = getvar(ncfile, 'pressure') variable_pressure = interplevel(variable, p, pressure_level) variable = variable_pressure if variable_name == 'wspd_wdir': ua = getvar(ncfile, 'ua') va = getvar(ncfile, 'va') u_pressure = interplevel(ua, p, pressure_level) v_pressure = interplevel(va, p, pressure_level) elif title_name == 'Updraft and Reflectivity': reflectivity = getvar(ncfile, 'REFD_MAX') elif title_name == 'Difference in Theta-E values': variable = getvar(ncfile, variable_name) p = getvar(ncfile, 'pressure') variable_pressure1 = interplevel(variable, p, '950') variable_pressure2 = interplevel(variable, p, '950') elif variable_name == 'ua': va = getvar(ncfile, 'va') p = getvar(ncfile, 'pressure') v_pressure = interplevel(va, p, pressure_level) u_wind = variable.squeeze() v_wind = v_pressure.squeeze() u_wind.attrs['units']='meters/second' v_wind.attrs['units']='meters/second' lats, lons = latlon_coords(variable) lats = lats.squeeze() lons = lons.squeeze() dx, dy = mpcalc.lat_lon_grid_deltas(to_np(lons), to_np(lats)) divergence = mpcalc.divergence(u_wind, v_wind, dx, dy, dim_order='yx') divergence = divergence*1e3 # Define cart projection lats, lons = latlon_coords(variable) cart_proj = ccrs.LambertConformal(central_longitude=8.722206, central_latitude=46.73585) bounds = geo_bounds(wrfin=ncfile) # Create figure fig = plt.figure(figsize=(15, 10)) if variable_name == 'slp': fig.patch.set_facecolor('k') ax = plt.axes(projection=cart_proj) ### Set map extent ### domain_extent = [3.701088, 13.814863, 43.85472,49.49499] if subset == True: ax.set_extent([subset_extent[0],subset_extent[1], subset_extent[2],subset_extent[3]], ccrs.PlateCarree()) else: ax.set_extent([domain_extent[0]+0.7,domain_extent[1]-0.7, domain_extent[2]+0.1,domain_extent[3]-0.1], ccrs.PlateCarree()) # Plot contour of variables levels_num = 11 levels = np.linspace(variable_min, variable_max, levels_num) # Creating new colormap for diverging colormaps def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100): new_cmap = LinearSegmentedColormap.from_list( 'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval), cmap(np.linspace(minval, maxval, n))) return new_cmap cmap = plt.get_cmap('RdYlBu') if title_name == 'CIN': cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, start=.5, rot=-.75, reverse=True)) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, transform=ccrs.PlateCarree(), extend='max', cmap=cmap) initiation_color = 'r*' elif variable_name == 'ctt': cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, start=.5, rot=-.75, reverse=True)) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, transform=ccrs.PlateCarree(), extend='both', cmap=cmap) initiation_color = 'r*' elif variable_name == 'pvo': cmap = plt.get_cmap('RdYlBu_r') new_cmap = truncate_colormap(cmap, 0.05, 0.9) new_norm = DivergingNorm(vmin=-1., vcenter=2., vmax=10) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, transform=ccrs.PlateCarree(), cmap=new_cmap, extend='both', norm=new_norm) initiation_color = 'k*' elif variable_name == 'avo': cmap = plt.get_cmap('RdYlBu_r') new_cmap = truncate_colormap(cmap, 0.05, 0.9) new_norm = DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, transform=ccrs.PlateCarree(), cmap=new_cmap, extend='both', norm=new_norm) initiation_color = 'k*' elif variable_name == 'omega': new_cmap = truncate_colormap(cmap, 0.05, 0.9) new_norm = DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, transform=ccrs.PlateCarree(), cmap=new_cmap, extend='both', norm=new_norm) initiation_color = 'k*' elif variable_name == 'ua': new_cmap = truncate_colormap(cmap, 0.05, 0.9) new_norm = DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max) variable_plot = plt.contourf(to_np(lons), to_np(lats), divergence, levels=levels, transform=ccrs.PlateCarree(), cmap=new_cmap, extend='both', norm=new_norm) initiation_color = 'k*' elif variable_name == 'UP_HELI_MAX' or variable_name == 'W_UP_MAX' or variable_name == 'QVAPOR': cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, start=.5, rot=-.75)) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, extend='max', transform=ccrs.PlateCarree(),cmap=cmap) initiation_color = 'r*' elif variable_name == 'theta_e' or variable_name == 't2': cmap = ListedColormap(sns.cubehelix_palette(levels_num-1, start=.5, rot=-.75)) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, extend='both', transform=ccrs.PlateCarree(),cmap=cmap) initiation_color = 'r*' elif variable_name == 'REFD_MAX': levels = np.arange(5., 75., 5.) dbz_rgb = np.array([[4,233,231], [1,159,244], [3,0,244], [2,253,2], [1,197,1], [0,142,0], [253,248,2], [229,188,0], [253,149,0], [253,0,0], [212,0,0], [188,0,0],[248,0,253], [152,84,198]], np.float32) / 255.0 dbz_cmap, dbz_norm = from_levels_and_colors(levels, dbz_rgb, extend='max') variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, extend='max', transform=ccrs.PlateCarree(), cmap=dbz_cmap, norm=dbz_norm) initiation_color = 'r*' elif variable_name == 'slp': ax.background_patch.set_fill(False) wslice = slice(1, None, 12) # Plot 850-hPa wind vectors vectors850 = ax.quiver(to_np(lons)[wslice, wslice], to_np(lats)[wslice, wslice], to_np(u_wind850)[wslice, wslice], to_np(v_wind850)[wslice, wslice], headlength=4, headwidth=3, scale=400, color='gold', label='850mb wind', transform=ccrs.PlateCarree(), zorder=2) # Plot 500-hPa wind vectors vectors500 = ax.quiver(to_np(lons)[wslice, wslice], to_np(lats)[wslice, wslice], to_np(u_wind500)[wslice, wslice], to_np(v_wind500)[wslice, wslice], headlength=4, headwidth=3, scale=400, color='cornflowerblue', zorder=2, label='500mb wind', transform=ccrs.PlateCarree()) # Plot 500-850 shear shear = ax.quiver(to_np(lons[wslice, wslice]), to_np(lats[wslice, wslice]), to_np(u_wind500[wslice, wslice]) - to_np(u_wind850[wslice, wslice]), to_np(v_wind500[wslice, wslice]) - to_np(v_wind850[wslice, wslice]), headlength=4, headwidth=3, scale=400, color='deeppink', zorder=2, label='500-850mb shear', transform=ccrs.PlateCarree()) contour = ax.contour(to_np(lons), to_np(lats), slp, levels=levels, colors='lime', linewidths=2, alpha=0.5, zorder=1, transform=ccrs.PlateCarree()) ax.clabel(contour, fontsize=12, inline=1, inline_spacing=4, fmt='%i') # Add a legend ax.legend(('850mb wind', '500mb wind', '500-850mb shear'), loc=4) # Manually set colors for legend legend = ax.get_legend() legend.legendHandles[0].set_color('gold') legend.legendHandles[1].set_color('cornflowerblue') legend.legendHandles[2].set_color('deeppink') initiation_color = 'w*' else: cmap = ListedColormap(sns.cubehelix_palette(10, start=.5, rot=-.75)) variable_plot = plt.contourf(to_np(lons), to_np(lats), to_np(variable), levels=levels, transform=ccrs.PlateCarree(),cmap=cmap) initiation_color = 'r*' # Plot reflectivity contours with colorbar if title_name == 'Updraft and Reflectivity': dbz_levels = np.arange(35., 75., 5.) dbz_rgb = np.array([[253,248,2], [229,188,0], [253,149,0], [253,0,0], [212,0,0], [188,0,0],[248,0,253], [152,84,198]], np.float32) / 255.0 dbz_cmap, dbz_norm = from_levels_and_colors(dbz_levels, dbz_rgb, extend='max') contours = plt.contour(to_np(lons), to_np(lats), to_np(reflectivity), levels=dbz_levels, transform=ccrs.PlateCarree(), cmap=dbz_cmap, norm=dbz_norm, linewidths=1) cbar_refl = mpu.colorbar(contours, ax, orientation='horizontal', aspect=10, shrink=.5, pad=0.05) cbar_refl.set_label('Maximum Derived Radar Reflectivity' '[$dBZ$]', fontsize=12.5) colorbar_lines = cbar_refl.ax.get_children() colorbar_lines[0].set_linewidths([10]*5) # Add wind quivers for every 10th data point if variable_name == 'wspd_wdir': plt.quiver(to_np(lons[::10,::10]), to_np(lats[::10,::10]), to_np(u_pressure[::10, ::10]), to_np(v_pressure[::10, ::10]), transform=ccrs.PlateCarree()) # Plot colorbar if variable_name == 'slp': pass else: cbar = mpu.colorbar(variable_plot, ax, orientation='vertical', aspect=40, shrink=.05, pad=0.05) cbar.set_label(colorbar_label, fontsize=15) cbar.set_ticks(levels) # Add borders and coastlines if variable_name == 'slp': ax.add_feature(cfeature.BORDERS.with_scale('10m'), edgecolor='white', linewidth=2) ax.add_feature(cfeature.COASTLINE.with_scale('10m'), edgecolor='white', linewidth=2) else: ax.add_feature(cfeature.BORDERS.with_scale('10m'), linewidth=0.8) ax.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=0.8) ### Add initiation location ### if initiation == True: ax.plot(initiation_location.lon, initiation_location.lat, initiation_color, markersize=20, transform=ccrs.PlateCarree()) # Add gridlines lon = np.arange(0, 20, 1) lat = np.arange(40, 60, 1) gl = ax.gridlines(xlocs=lon, ylocs=lat, zorder=3) # Add tick labels mpu.yticklabels(lat, ax=ax, fontsize=12.5) mpu.xticklabels(lon, ax=ax, fontsize=12.5) # Make nicetime file_name = '{}wrfout_d02_{}_{}:{}:00'.format(data_dir, date, time, minutes) xr_file = xr.open_dataset(file_name) nicetime = pd.to_datetime(xr_file.QVAPOR.isel(Time=0).XTIME.values) nicetime = nicetime.strftime('%Y-%m-%d %H:%M') # Add plot title if pressure_level != False: ax.set_title('{} @ {} hPa'.format(title_name, pressure_level), loc='left', fontsize=15) ax.set_title('Valid time: {} UTC'.format(nicetime), loc='right', fontsize=15) else: if variable_name == 'slp': ax.set_title(title_name, loc='left', fontsize=15, color='white') ax.set_title('Valid time: {} UTC'.format(nicetime), loc='right', fontsize=15, color='white') else: ax.set_title(title_name, loc='left', fontsize=20) ax.set_title('Valid time: {} UTC'.format(nicetime), loc='right', fontsize=15) plt.show() ### Save figure ### if save == True: if pressure_level != False: if subset == True: fig.savefig('{}/{}/horizontal_map_{}_subset_{}_{}_{}:{}.png'.format( save_dir, save_name, save_name, pressure_level, date, time, minutes), bbox_inches='tight', dpi=300) else: fig.savefig('{}/{}/horizontal_map_{}_{}_{}_{}:{}.png'.format( save_dir, save_name, save_name, pressure_level, date, time, minutes), bbox_inches='tight', dpi=300) else: if subset == True: fig.savefig('{}/{}/horizontal_map_{}_subset_{}_{}:{}.png'.format( save_dir, save_name, save_name, date, time, minutes), bbox_inches='tight', dpi=300, facecolor=fig.get_facecolor()) else: fig.savefig('{}/{}/horizontal_map_{}_{}_{}:{}.png'.format( save_dir, save_name, save_name, date, time, minutes), bbox_inches='tight', dpi=300, facecolor=fig.get_facecolor()) ### Make a GIF from the plots ### if gif == True: # Predifine some variables gif_data_dir = save_dir + save_name gif_save_dir = '{}gifs/'.format(save_dir) gif_save_name = 'horizontal_map_{}.gif'.format(save_name) # GIF creating procedure os.chdir(gif_data_dir) image_folder = os.fsencode(gif_data_dir) filenames = [] for file in os.listdir(image_folder): filename = os.fsdecode(file) if filename.endswith( ('.png') ): filenames.append(filename) filenames.sort() images = list(map(lambda filename: imageio.imread(filename), filenames)) imageio.mimsave(os.path.join(gif_save_dir + gif_save_name), images, duration = 0.50)
h.add_grid(increment=20) # Add wind speed colored line cmap = ListedColormap(sns.cubehelix_palette(10, start=.5, rot=-.75)) levels = np.linspace(0, 20, 11) wind_speed_h = h.plot_colormapped(u, v, wind_speed, intervals=levels, cmap=cmap) # Add color bar for hodograph cbar_h = mpu.colorbar(wind_speed_h, ax_hod, orientation='vertical', aspect=30, shrink=.05, pad=0.1, extend='max') cbar_h.set_label('Wind Speed [$kn$]', fontsize=10) cbar_h.set_ticks(levels) # Set label of axes skew.ax.set_ylabel('Pressure [$hPa$]', fontsize=12.5) skew.ax.set_xlabel('Temperature [$°C$]', fontsize=12.5) # Make nicetime nicetime = pd.to_datetime(date) # Add title skew.ax.set_title('')
def cross_section(variable_name, date, time, start_lat, start_lon, end_lat, end_lon, save=False): '''This function plots a vertical cross section of the chosen variable. Supported variables for plotting procedure are vertical_velocity, rh, omega, absolute_vorticity, theta_e and reflectivity.''' ### Predefine some variables ### # Define data filename data_dir = '/scratch3/thomasl/work/data/casestudy_baden/' filename = '{}wrfout_d02_{}_{}:00'.format(data_dir, date, time) # Define save directory save_dir = '/scratch3/thomasl/work/retrospective_part/' 'casestudy_baden/cross_section/' # Create the start point and end point for the cross section start_point = CoordPair(lat=start_lat, lon=start_lon) end_point = CoordPair(lat=end_lat, lon=end_lon) ### Start plotting procedure ### # Open NetCDF file ncfile = Dataset(filename) # Extract the model height, terrain height and variables ht = getvar(ncfile, 'z') / 1000 # change to km ter = getvar(ncfile, 'ter') / 1000 if variable_name == 'vertical_velocity': variable = getvar(ncfile, 'wa', units='kt') title_name = 'Vertical Velocity' colorbar_label = 'Vertical Velocity [$kn$]' variable_min = -2 variable_max = 2 elif variable_name == 'rh': variable = getvar(ncfile, 'rh') title_name = 'Relative Humidity' colorbar_label = 'Relative Humidity [$pct$]' variable_min = 0 variable_max = 100 elif variable_name == 'omega': variable = getvar(ncfile, 'omega') title_name = 'Vertical Motion (Omega)' colorbar_label = 'Omega [$Pa$ $s^-$$^1$]' variable_min = -5 variable_max = 5 elif variable_name == 'absolute_vorticity': variable = getvar(ncfile, 'avo') title_name = 'Absolute Vorticity' colorbar_label = 'Absolute Vorticity [$10^{-5}$' '$s^{-1}$]' variable_min = -50 variable_max = 100 elif variable_name == 'theta_e': variable = getvar(ncfile, 'theta_e') title_name = 'Theta-E' colorbar_label = 'Theta-E [$K$]' variable_min = 315 variable_max = 335 elif variable_name == 'reflectivity': variable = getvar(ncfile, 'dbz') #, timeidx=-1 title_name = 'Reflectivity' colorbar_label = 'Reflectivity [$dBZ$]' variable_min = 5 variable_max = 75 # Linear Z for interpolation Z = 10**(variable / 10) # Compute the vertical cross-section interpolation z_cross = vertcross(Z, ht, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True) # Convert back after interpolation variable_cross = 10.0 * np.log10(z_cross) # Make a copy of the z cross data variable_cross_filled = np.ma.copy(to_np(variable_cross)) # For each cross section column, find the first index with # non-missing values and copy these to the missing elements below for i in range(variable_cross_filled.shape[-1]): column_vals = variable_cross_filled[:, i] first_idx = int(np.transpose((column_vals > -200).nonzero())[0]) variable_cross_filled[0:first_idx, i] = variable_cross_filled[first_idx, i] ter_line = interpline(ter, wrfin=ncfile, start_point=start_point, end_point=end_point) # Get latitude and longitude points lats, lons = latlon_coords(variable) # Create the figure fig = plt.figure(figsize=(15, 10)) ax = plt.axes() ys = to_np(variable_cross.coords['vertical']) xs = np.arange(0, variable_cross.shape[-1], 1) # Make contour plot if variable_name == 'reflectivity': levels = np.arange(variable_min, variable_max, 5) # Create the dbz color table found on NWS pages. dbz_rgb = np.array( [[4, 233, 231], [1, 159, 244], [3, 0, 244], [2, 253, 2], [1, 197, 1], [0, 142, 0], [253, 248, 2], [229, 188, 0], [253, 149, 0], [253, 0, 0], [212, 0, 0], [188, 0, 0], [248, 0, 253], [152, 84, 198]], np.float32) / 255.0 dbz_cmap, dbz_norm = from_levels_and_colors(levels, dbz_rgb, extend='max') else: levels = np.linspace(variable_min, variable_max, 11) if variable_name == 'omega' or variable_name == 'vertical_velocity': def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100): new_cmap = colors.LinearSegmentedColormap.from_list( 'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval), cmap(np.linspace(minval, maxval, n))) return new_cmap old_cmap = plt.get_cmap('RdYlBu') cmap = truncate_colormap(old_cmap, 0.05, 0.9) norm = colors.DivergingNorm(vmin=variable_min, vcenter=0, vmax=variable_max) else: cmap = ListedColormap(sns.cubehelix_palette(20, start=.5, rot=-.75)) if variable_name == 'omega' or variable_name == 'vertical_velocity': variable_contours = ax.contourf(xs, ys, to_np(variable_cross_filled), levels=levels, cmap=cmap, extend='both', norm=norm) elif variable_name == 'rh': variable_contours = ax.contourf(xs, ys, to_np(variable_cross_filled), levels=levels, cmap=cmap, extend='max') elif variable_name == 'reflectivity': variable_contours = ax.contourf(xs, ys, to_np(variable_cross_filled), levels=levels, cmap=dbz_cmap, norm=dbz_norm, extend='both') else: variable_contours = ax.contourf(xs, ys, to_np(variable_cross_filled), levels=levels, cmap=cmap, extend='both') # Plot wind barbs if variable_name == 'vertical_velocity': u = getvar(ncfile, 'ua', units='kt') U = 10**(u / 10) u_cross = vertcross(U, ht, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True) u_cross = 10.0 * np.log10(u_cross) u_cross_filled = np.ma.copy(to_np(u_cross)) for i in range(u_cross_filled.shape[-1]): column_vals = u_cross_filled[:, i] first_idx = int(np.transpose((column_vals > -200).nonzero())[0]) u_cross_filled[0:first_idx, i] = u_cross_filled[first_idx, i] ax.barbs(xs[::3], ys[::3], to_np(u_cross_filled[::3, ::3]), to_np(variable_cross_filled[::3, ::3]), length=7, zorder=1) if variable_name == 'omega': u = getvar(ncfile, 'ua', units='kt') U = 10**(u / 10) u_cross = vertcross(U, ht, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True) u_cross = 10.0 * np.log10(u_cross) u_cross_filled = np.ma.copy(to_np(u_cross)) for i in range(u_cross_filled.shape[-1]): column_vals = u_cross_filled[:, i] first_idx = int(np.transpose((column_vals > -200).nonzero())[0]) u_cross_filled[0:first_idx, i] = u_cross_filled[first_idx, i] w = getvar(ncfile, 'wa', units='kt') W = 10**(w / 10) w_cross = vertcross(W, ht, wrfin=ncfile, start_point=start_point, end_point=end_point, latlon=True, meta=True) w_cross = 10.0 * np.log10(w_cross) w_cross_filled = np.ma.copy(to_np(w_cross)) for i in range(w_cross_filled.shape[-1]): column_vals = w_cross_filled[:, i] first_idx = int(np.transpose((column_vals > -200).nonzero())[0]) w_cross_filled[0:first_idx, i] = w_cross_filled[first_idx, i] ax.barbs(xs[::3], ys[::3], to_np(u_cross_filled[::3, ::3]), to_np(w_cross_filled[::3, ::3]), length=7, zorder=1, color='grey') # Add color bar cbar = mpu.colorbar(variable_contours, ax, orientation='vertical', aspect=40, shrink=.05, pad=0.05) cbar.set_label(colorbar_label, fontsize=15) cbar.set_ticks(levels) # Set x-ticks to use latitude and longitude labels coord_pairs = to_np(variable_cross.coords['xy_loc']) x_ticks = np.arange(coord_pairs.shape[0]) x_labels = [ pair.latlon_str(fmt='{:.2f}, {:.2f}') for pair in to_np(coord_pairs) ] # Set desired number of x ticks below num_ticks = 5 thin = int((len(x_ticks) / num_ticks) + .5) ax.set_xticks(x_ticks[::thin]) ax.set_xticklabels(x_labels[::thin], rotation=45, fontsize=10) ax.set_xlim(x_ticks[0], x_ticks[-1]) # Set y-ticks and limit the height ax.set_yticks(np.linspace(0, 12, 13)) ax.set_ylim(0, 12) # Set x-axis and y-axis labels ax.set_xlabel('Latitude, Longitude', fontsize=12.5) ax.set_ylabel('Height [$km$]', fontsize=12.5) # Fill in mountian area ht_fill = ax.fill_between(xs, 0, to_np(ter_line), facecolor='saddlebrown', zorder=2) # Make nicetime xr_file = xr.open_dataset(filename) nicetime = pd.to_datetime(xr_file.QVAPOR.isel(Time=0).XTIME.values) # Add title ax.set_title('Vertical Cross-Section of {}'.format(title_name), fontsize=20, loc='left') ax.set_title('Valid time: {} {}'.format( nicetime.strftime('%Y-%m-%d %H:%M'), 'UTC'), fontsize=15, loc='right') # Add grid for y axis ax.grid(axis='y', linestyle='--', color='grey') plt.show() ### Save figure ### if save == True: fig.savefig('{}cross_section_{}.png'.format(save_dir, variable_name), bbox_inches='tight', dpi=300)
def lagranto_plotting(traj_variable_name, start_time, end_time, trajs_bunch_level='all', subset=False, save=False): '''This function plots the chosen variables for the trajectories calculated with Lagranto. Supported variables for plotting procedure are water_vapor, updraft and height.''' ### Predefine some variables ### traj_data_dir = '/scratch3/thomasl/work/retrospective_part/lagranto/' 'traj_baden_10000_every1000_area_1200.ll' save_dir = '/scratch3/thomasl/work/retrospective_part' '/casestudy_baden/lagranto/' start_locations = 'area' # distinction between single and multiple # starting points of trajectories number_trajs_plot = 1 # Location of Initiation lat = 47.25 lon = 7.85 initiation = CoordPair(lat, lon) # Change extent of plot subset_extent = [7, 9, 47, 48] # Variables for getting PBL height of WRF model data date = '2018-05-30' time = '16:10' wrf_filename = '/scratch3/thomasl/work/data/casestudy_baden/' 'wrfout_d02_{}_{}:00'.format( date, time) # Variables: if traj_variable_name == 'water_vapor': traj_variable_name = 'QVAPOR' title_name = 'Trajectories of Water Vapor' colorbar_label_trajs = 'Water Vapor Mixing Ratio [$g$ $kg^{-1}$]' save_name = 'trajectory_water_vapor_{}_{}'.format(start_time, end_time) traj_variable_min = 0 traj_variable_max = 15 elif traj_variable_name == 'updraft': traj_variable_name = 'W_UP_MAX' title_name = 'Trajectories of Updraft' colorbar_label_trajs = 'Max Z-Wind Updraft [$m$ $s^-$$^1$]' save_name = 'trajectory_updraft_{}_{}'.format(start_time, end_time) traj_variable_min = 0 traj_variable_max = 10 elif traj_variable_name == 'height': traj_variable_name = 'z' title_name = 'Height of Trajectories' colorbar_label_trajs = 'Height of Trajectories [$m$]' save_name = 'trajectory_height_{}_{}'.format(start_time, end_time) traj_variable_min = 0 traj_variable_max = 10000 ### Plotting procedure ### trajs = Tra() trajs.load_ascii(traj_data_dir) # Get PBL out of WRF model data ncfile = Dataset(wrf_filename) wrf_file = xr.open_dataset(wrf_filename) data = wrf_file.PBLH location = ll_to_xy(ncfile, lat, lon) data_point = data.sel(west_east=location[0], south_north=location[1]) pbl = data_point.values # Separate trajectories in 3 vertical bunches # Trajectories of pbl (according to pbl height of WRF model data) trajspbl = [] for t in trajs: if (t['z'][0] <= pbl): trajspbl.append(t) # Trajectories between pbl and 5000 m trajs5 = [] for t in trajs: if (t['z'][0] > pbl and t['z'][0] < 5000): trajs5.append(t) # Trajectories between 5000 m and 10000 m trajs10 = [] for t in trajs: if (t['z'][0] > 5000 and t['z'][0] <= 10000): trajs10.append(t) if trajs_bunch_level == 'pbl': trajs_bunch = trajspbl elif trajs_bunch_level == '5': trajs_bunch = trajs5 elif trajs_bunch_level == '10': trajs_bunch = trajs10 elif trajs_bunch_level == 'all': trajs_bunch = trajs # Get terrain height terrain_height = getvar(ncfile, 'HGT') / 1000 # change to km # Define cart projection lats, lons = latlon_coords(terrain_height) cart_proj = ccrs.LambertConformal(central_longitude=8.722206, central_latitude=46.73585) # Create figure fig = plt.figure(figsize=(15, 10)) ax = plt.axes(projection=cart_proj) ### Set map extent ### domain_extent = [3.701088, 13.814863, 43.85472, 49.49499] if subset == True: ax.set_extent([ subset_extent[0], subset_extent[1], subset_extent[2], subset_extent[3] ], ccrs.PlateCarree()) else: ax.set_extent([ domain_extent[0] + 0.7, domain_extent[1] - 0.7, domain_extent[2] + 0.1, domain_extent[3] - 0.1 ], ccrs.PlateCarree()) # Plot trajectories levels_trajs = np.linspace(traj_variable_min, traj_variable_max, 11) rounded_levels_trajs = [round(elem, 1) for elem in levels_trajs] cmap = ListedColormap(sns.cubehelix_palette( 10, start=.5, rot=-.75, )) plt_trajs = plot_trajs(ax, trajs_bunch[0::number_trajs_plot], traj_variable_name, linewidth=2, levels=rounded_levels_trajs, cmap=cmap) # Plot the terrain height with colorbar levels = np.linspace(0, 4, 21) terrain = plt.contourf(to_np(lons), to_np(lats), to_np(terrain_height), levels=levels, transform=ccrs.PlateCarree(), cmap=get_cmap('Greys'), alpha=0.75) cbar = mpu.colorbar(terrain, ax, orientation='horizontal', aspect=40, shrink=.05, pad=0.075) cbar.set_label('Terrain Height [$km$]', fontsize=15) cbar.set_ticks(levels) # Make only every second color bar tick label visible for label in cbar.ax.xaxis.get_ticklabels()[1::2]: label.set_visible(False) # Add color bar for trajectory variable if traj_variable_name == 'QVAPOR': extend = 'both' else: extend = 'max' cbar_trajs = mpu.colorbar(plt_trajs, ax, orientation='vertical', aspect=40, shrink=.05, pad=0.05, extend=extend) cbar_trajs.set_label(colorbar_label_trajs, fontsize=15) cbar_trajs.set_ticks(rounded_levels_trajs) # Add borders and coastlines ax.add_feature(cfeature.BORDERS.with_scale('10m'), linewidth=0.8) ax.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=0.8) # Add cross for initiation location for t in trajs: ax.plot(t['lon'][0], t['lat'][0], 'kx', transform=ccrs.PlateCarree()) # Add gridlines lon = np.arange(0, 20, 1) lat = np.arange(40, 60, 1) gl = ax.gridlines(xlocs=lon, ylocs=lat, zorder=3) # Add tick labels mpu.yticklabels(lat, ax=ax, fontsize=12.5) mpu.xticklabels(lon, ax=ax, fontsize=12.5) # Set title ax.set_title(title_name, loc='left', fontsize=20) ax.set_title('Time Range: {} - {} UTC'.format(start_time, end_time), loc='right', fontsize=15) plt.show() ### Save figure ### if save == True: if subset == True: if trajs_bunch_level == 'all': fig.savefig('{}{}_subset_{}.png'.format( save_dir, save_name, start_locations), bbox_inches='tight', dpi=300) else: fig.savefig('{}{}_subset_{}_{}.png'.format( save_dir, save_name, trajs_bunch_level, start_locations), bbox_inches='tight', dpi=300) else: if trajs_bunch_level == 'all': fig.savefig('{}{}_{}.png'.format(save_dir, save_name, start_locations), bbox_inches='tight', dpi=300) else: fig.savefig('{}{}_{}_{}.png'.format(save_dir, save_name, trajs_bunch_level, start_locations), bbox_inches='tight', dpi=300)