def plot_sounding(date, station): p, T, Td, u, v, windspeed = get_sounding_data(date, station) lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) lfc_pressure, lfc_temperature = mpcalc.lfc(p, T, Td) parcel_path = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') # Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(8, 8)) skew = SkewT(fig) # Plot the data temperature_line, = skew.plot(p, T, color='tab:red') dewpoint_line, = skew.plot(p, Td, color='blue') cursor = mplcursors.cursor([temperature_line, dewpoint_line]) # Plot thermodynamic parameters and parcel path skew.plot(p, parcel_path, color='black') if lcl_pressure: skew.ax.axhline(lcl_pressure, color='black') if lfc_pressure: skew.ax.axhline(lfc_pressure, color='0.7') # Add the relevant special lines skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Shade areas representing CAPE and CIN skew.shade_cin(p, T, parcel_path) skew.shade_cape(p, T, parcel_path) # Add wind barbs skew.plot_barbs(p, u, v) # Add an axes to the plot ax_hod = inset_axes(skew.ax, '30%', '30%', loc=1, borderpad=3) # Plot the hodograph h = Hodograph(ax_hod, component_range=100.) # Grid the hodograph h.add_grid(increment=20) # Plot the data on the hodograph mask = (p >= 100 * units.mbar) h.plot_colormapped(u[mask], v[mask], windspeed[mask]) # Plot a line colored by wind speed # Set some sensible axis limits skew.ax.set_ylim(1000, 100) skew.ax.set_xlim(-40, 60) return fig, skew
def plot_sounding(date, station): p, T, Td, u, v, windspeed = get_sounding_data(date, station) lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) lfc_pressure, lfc_temperature = mpcalc.lfc(p, T, Td) parcel_path = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') # Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(8, 8)) skew = SkewT(fig) # Plot the data temperature_line, = skew.plot(p, T, color='tab:red') dewpoint_line, = skew.plot(p, Td, color='blue') cursor = mplcursors.cursor([temperature_line, dewpoint_line]) # Plot thermodynamic parameters and parcel path skew.plot(p, parcel_path, color='black') if lcl_pressure: skew.ax.axhline(lcl_pressure, color='black') if lfc_pressure: skew.ax.axhline(lfc_pressure, color='0.7') # Add the relevant special lines skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Shade areas representing CAPE and CIN skew.shade_cin(p, T, parcel_path) skew.shade_cape(p, T, parcel_path) # Add wind barbs skew.plot_barbs(p, u, v) # Add an axes to the plot ax_hod = inset_axes(skew.ax, '30%', '30%', loc=1, borderpad=3) # Plot the hodograph h = Hodograph(ax_hod, component_range=100.) # Grid the hodograph h.add_grid(increment=20) # Plot the data on the hodograph mask = (p >= 100 * units.mbar) h.plot_colormapped(u[mask], v[mask], windspeed[mask]) # Plot a line colored by wind speed # Set some sensible axis limits skew.ax.set_ylim(1000, 100) skew.ax.set_xlim(-40, 60) return fig, skew
def test_hodograph_units(): """Test passing unit-ed quantities to Hodograph.""" fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax) u = np.arange(10) * units.kt v = np.arange(10) * units.kt hodo.plot(u, v) hodo.plot_colormapped(u, v, np.sqrt(u * u + v * v), cmap='Greys') return fig
def test_hodograph_units(): """Test passing unit-ed quantities to Hodograph.""" fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax) u = np.arange(10) * units.kt v = np.arange(10) * units.kt hodo.plot(u, v) hodo.plot_colormapped(u, v, np.sqrt(u * u + v * v), cmap='Greys') return fig
def test_hodograph_api(): """Basic test of Hodograph API.""" fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=60) hodo.add_grid(increment=5, color='k') hodo.plot([1, 10], [1, 10], color='red') hodo.plot_colormapped(np.array([1, 3, 5, 10]), np.array([2, 4, 6, 11]), np.array([0.1, 0.3, 0.5, 0.9]), cmap='Greys') return fig
def test_hodograph_api(): """Basic test of Hodograph API.""" fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=60) hodo.add_grid(increment=5, color='k') hodo.plot([1, 10], [1, 10], color='red') hodo.plot_colormapped(np.array([1, 3, 5, 10]), np.array([2, 4, 6, 11]), np.array([0.1, 0.3, 0.5, 0.9]), cmap='Greys') return fig
def test_plot_colormapped_bounds_deprecation(): """Test deprecation of bounds kwarg in `plot_colormapped`.""" u = np.zeros((6)) * units.knots v = np.array([0, 10, 20, 30, 40, 50]) * units.knots heights = np.array([0, 1000, 2000, 3000, 4000, 5000]) * units.m intervals = np.array([500, 1500, 2500, 3500, 4500]) * units.m colors = ['r', 'g', 'b', 'r'] fig = plt.figure(figsize=(7, 7)) ax1 = fig.add_subplot(1, 1, 1) h = Hodograph(ax1) h.plot_colormapped(u, v, heights, colors=colors, bounds=intervals)
def test_hodograph_plot_colormapped(): """Test hodograph colored line with NaN values.""" u = np.arange(5., 65., 5) v = np.arange(-5., -65., -5) u[3] = np.nan v[6] = np.nan fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=80) hodo.add_grid(increment=20, color='k') hodo.plot_colormapped(u, v, np.hypot(u, v), cmap='Greys') return fig
def test_hodograph_plot_colormapped(): """Test hodograph colored line with NaN values.""" u = np.arange(5., 65., 5) v = np.arange(-5., -65., -5) u[3] = np.nan v[6] = np.nan fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=80) hodo.add_grid(increment=20, color='k') hodo.plot_colormapped(u, v, np.hypot(u, v), cmap='Greys') return fig
def test_hodograph_plot_arbitrary_layer(): """Test hodograph colored layers for arbitrary variables without interpolation.""" u = np.arange(5, 65, 5) * units('knot') v = np.arange(-5, -65, -5) * units('knot') speed = np.sqrt(u ** 2 + v ** 2) colors = ['red', 'green', 'blue'] levels = [0, 10, 20, 30] * units('knot') fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=80) hodo.add_grid(increment=20, color='k') hodo.plot_colormapped(u, v, speed, bounds=levels, colors=colors) return fig
def test_hodograph_plot_arbitrary_layer(): """Test hodograph colored layers for arbitrary variables without interpolation.""" u = np.arange(5, 65, 5) * units('knot') v = np.arange(-5, -65, -5) * units('knot') speed = np.sqrt(u**2 + v**2) colors = ['red', 'green', 'blue'] levels = [0, 10, 20, 30] * units('knot') fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=80) hodo.add_grid(increment=20, color='k') hodo.plot_colormapped(u, v, speed, bounds=levels, colors=colors) return fig
def test_hodograph_plot_layers_bound_units(): """Test hodograph colored height layers with interpolation and different units.""" u = np.zeros((6)) * units.knots v = np.array([0, 10, 20, 30, 40, 50]) * units.knots heights = np.array([0, 1000, 2000, 3000, 4000, 5000]) * units.m bounds = np.array([0.5, 1.5, 2.5, 3.5, 4.5]) * units.km colors = ['r', 'g', 'b', 'r'] fig = plt.figure(figsize=(7, 7)) ax1 = fig.add_subplot(1, 1, 1) h = Hodograph(ax1) h.add_grid(increment=10) h.plot_colormapped(u, v, heights, colors=colors, bounds=bounds) ax1.set_xlim(-50, 50) ax1.set_ylim(-5, 50) return fig
def test_hodograph_plot_layers_different_units(): """Test hodograph colored height layers with interpolation and different units.""" u = np.zeros(6) * units.knots v = np.array([0, 10, 20, 30, 40, 50]) * units.knots heights = np.array([0, 1, 2, 3, 4, 5]) * units.km intervals = np.array([500, 1500, 2500, 3500, 4500]) * units.m colors = ['r', 'g', 'b', 'r'] fig = plt.figure(figsize=(7, 7)) ax1 = fig.add_subplot(1, 1, 1) h = Hodograph(ax1) h.add_grid(increment=10) h.plot_colormapped(u, v, heights, colors=colors, intervals=intervals) ax1.set_xlim(-50, 50) ax1.set_ylim(-5, 50) return fig
def test_hodograph_plot_layers_bound_units(): """Test hodograph colored height layers with interpolation and different units.""" u = np.zeros((6)) * units.knots v = np.array([0, 10, 20, 30, 40, 50]) * units.knots heights = np.array([0, 1000, 2000, 3000, 4000, 5000]) * units.m bounds = np.array([0.5, 1.5, 2.5, 3.5, 4.5]) * units.km colors = ['r', 'g', 'b', 'r'] fig = plt.figure(figsize=(7, 7)) ax1 = fig.add_subplot(1, 1, 1) h = Hodograph(ax1) h.add_grid(increment=10) h.plot_colormapped(u, v, heights, colors=colors, bounds=bounds) ax1.set_xlim(-50, 50) ax1.set_ylim(-5, 50) return fig
def test_hodograph_plot_layers(): """Test hodograph colored height layers with interpolation.""" u = np.arange(5, 65, 5) * units('knot') v = np.arange(-5, -65, -5) * units('knot') h = [178, 213, 610, 656, 721, 914, 1060, 1219, 1372, 1412, 1512, 1524 ] * units('meter') colors = ['red', 'green'] levels = [0, 500, 1000] * units('meter') fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=80) hodo.add_grid(increment=20, color='k') hodo.plot_colormapped(u, v, h, bounds=levels, colors=colors) return fig
def test_hodograph_masked_array(): """Basic test of Hodograph API.""" fig = plt.figure(figsize=(9, 9)) ax = fig.add_subplot(1, 1, 1) hodo = Hodograph(ax, component_range=20) u = np.ma.array([1, 3, 5, 10]) v = np.ma.array([2, 4, 6, 11]) h = units.Quantity(np.array([0.1, 3.5, 5.5, 10.9]), 'km') intervals = units.Quantity(np.array([0.0, 3.0, 6.0, 9.0, 12.0, 15.0]), 'km') colors = ['red', 'green', 'yellow', 'blue', 'purple'] # Check that we're not triggering interpolation warnings with warnings.catch_warnings(record=True) as record: hodo.plot_colormapped(u, v, h, intervals=intervals, colors=colors) assert len(record) == 0 return fig
def plot_skewt(df): # We will pull the data out of the example dataset into individual variables # and assign units. hght = df['height'].values * units.hPa p = df['pressure'].values * units.hPa T = df['temperature'].values * units.degC Td = df['dewpoint'].values * units.degC wind_speed = df['speed'].values * units.knots wind_dir = df['direction'].values * units.degrees u, v = mpcalc.wind_components(wind_speed, wind_dir) # Create a new figure. The dimensions here give a good aspect ratio. fig = plt.figure(figsize=(9, 12)) skew = SkewT(fig, rotation=45) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') skew.plot_barbs(p, u, v) skew.ax.set_ylim(1000, 100) skew.ax.set_xlim(-40, 60) # Calculate LCL height and plot as black dot lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Calculate full parcel profile and add to plot as black line prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') skew.plot(p, prof, 'k', linewidth=2) # An example of a slanted line at constant T -- in this case the 0 # isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph ax_hod = inset_axes(skew.ax, '40%', '40%', loc=2) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, hght) return skew
# Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(9, 9)) add_metpy_logo(fig, 115, 100) # Grid for plots skew = SkewT(fig, rotation=45) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') skew.plot_barbs(p, u, v) skew.ax.set_ylim(1000, 100) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Good bounds for aspect ratio skew.ax.set_xlim(-50, 60) # Create a hodograph ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, hght) # Show the plot plt.show()
skew.plot_dry_adiabats(linewidth=0.75) skew.plot_moist_adiabats(linewidth=0.75) skew.plot_mixing_lines(linewidth=0.75) # Hodograph ax_hod = fig5.add_subplot(gs[:2, 2:]) #gs.tight_layout(fig5) if np.nanmax(wind_kts) > 18: comprange = 35 else: comprange = 20 h = Hodograph(ax_hod, component_range=comprange) h.add_grid(increment=5) h.plot_colormapped(u, v, pres, cmap=cmocean.cm.deep_r) ax_hod.set_title('Hodograph (kts)') ax_hod.yaxis.set_ticklabels([]) #ax_hod.set_xlabel('Wind Speed (kts)') # Finland Map - ISOBAR if mission == 'ISOBAR': # llcrnrlat = 33.6 # urcrnrlat = 37.2 # llcrnrlon = -103.2 # urcrnrlon = -94.2 lllat = 55.34 urlat = 70.54 lat_0 = 65. lon_0 = 24. ax_map = fig5.add_subplot(gs[2, 2:])
skew.ax.set_ylim(1000, 100) skew.ax.set_xlim(-40, 60) # Plot LCL as black dot skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Plot the parcel profile as a black line skew.plot(p, parcel_prof, 'k', linewidth=2) # Shade areas of CAPE and CIN skew.shade_cin(p, T, parcel_prof) skew.shade_cape(p, T, parcel_prof) # Plot a zero degree isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph # Create an inset axes object that is 40% width and height of the # figure and put it in the upper right hand corner. ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, wind_speed) # Plot a line colored by wind speed # Show the plot plt.show()
def plotUAVskewT(filenamecsv): ''' Input filepath of post-processed uav data Outputs Skew-T log-p plot of UAV data, includes hodograph and some convective parameters ''' copdata = csvread_copter(filenamecsv) lat = copdata[0] lon = copdata[1] alt = copdata[2] pressure = copdata[3] temperature = copdata[4] dewpoint = copdata[5] speed = copdata[9] speed_kts = speed * 1.94 direction = copdata[10] site = findSite(lat[0], lon[0]) sitename, sitelong = site.split('/') fname = filenamecsv.split('\\')[-1] timeTakeoff = datetime.strptime(fname[:15], '%Y%m%d_%H%M%S') copterNum = fname[-10] u,v = mcalc.get_wind_components(speed_kts*units.kts, direction * units.deg) u = u.to(units.kts) v = v.to(units.kts) # Wind shear bulkshear = speed_kts[-3] - speed_kts[0] print '0-%d m Bulk Shear: %.0f kts' % (alt[-3], bulkshear) if np.isnan(dewpoint).all(): moist = 0 else: moist = 1 print 'Plotting...' fignum = plt.figure(figsize=(12,9)) gs = gridspec.GridSpec(4, 4) skew = SkewT(fignum, rotation=20, subplot=gs[:, :2]) skew.plot(pressure, temperature, 'r', linewidth = 2) skew.plot(pressure, dewpoint, 'g', linewidth = 2) skew.plot_barbs(pressure[0::4], u[0::4], v[0::4], x_clip_radius = 0.12, \ y_clip_radius = 0.12) # Plot convective parameters if moist: plcl, Tlcl, isbelowlcl, profile = parcelUAV(temperature, dewpoint, pressure) SBCAPE = uavCAPE(temperature * units.degC, profile, pressure * units.hPa) skew.plot(plcl, Tlcl, 'ko', markerfacecolor='black') skew.plot(pressure, profile, 'k', linewidth=2) else: isbelowlcl = 0 # set up plot limits and labels - use LCL as max if higher than profile # if moist: # xmin = math.floor(np.nanmin(dewpoint)) + 2 # else: # xmin = math.floor(np.nanmin(temperature)) # xmax = math.floor(np.nanmax(temperature)) + 20 xmin = 0. xmax = 50. if isbelowlcl: ymin = round((plcl / units.mbar), -1) - 10 else: ymin = round(np.nanmin(pressure),-1) - 10 ymax = round(np.nanmax(pressure),-1) + 10 skew.ax.set_ylim(ymax, ymin) skew.ax.set_xlim(xmin, xmax) skew.ax.set_yticks(np.arange(ymin, ymax+10, 10)) skew.ax.set_xlabel('Temperature ($^\circ$C)') skew.ax.set_ylabel('Pressure (hPa)') titleName = 'Coptersonde-%s %s UTC - %s' % (copterNum, timeTakeoff.strftime('%d-%b-%Y %H:%M:%S'), sitename) skew.ax.set_title(titleName) skew.plot_dry_adiabats(linewidth=0.75) skew.plot_moist_adiabats(linewidth=0.75) skew.plot_mixing_lines(linewidth=0.75) # Hodograph ax_hod = fignum.add_subplot(gs[:2,2:]) #gs.tight_layout(fig5) if np.nanmax(speed_kts) > 18: comprange = 35 else: comprange = 20 h = Hodograph(ax_hod, component_range=comprange) h.add_grid(increment=5) h.plot_colormapped(u, v, pressure, cmap=cmocean.cm.deep_r) ax_hod.set_title('Hodograph (kts)') ax_hod.yaxis.set_ticklabels([]) #ax_hod.set_xlabel('Wind Speed (kts)') # Map - Oklahoma llcrnrlat = 33.6 urcrnrlat = 37.2 llcrnrlon = -103.2 urcrnrlon = -94.2 ax_map = fignum.add_subplot(gs[2, 2:]) m = Basemap(projection='merc', llcrnrlat=llcrnrlat, urcrnrlat=urcrnrlat, llcrnrlon=llcrnrlon,urcrnrlon=urcrnrlon, lat_ts=20, resolution='l', ax=ax_map) print 'Basemap...' m.drawcounties() m.drawstates() x,y = m(lon[0], lat[0]) plt.plot(x,y,'b.') plt.text(x+40000, y-5000, sitelong, bbox=dict(facecolor='yellow', alpha=0.5)) if moist: # Convective parameter values ax_data = fignum.add_subplot(gs[3, 2]) plt.axis('off') datastr = 'LCL = %.0f hPa\nSBCAPE = %.0f J kg$^{-1}$\n0-%.0f m bulk shear\n\ = %.0f kts' % \ (plcl.magnitude, SBCAPE.magnitude, alt[-3], bulkshear) boxprops = dict(boxstyle='round', facecolor='none') ax_data.text(0.05, 0.95, datastr, transform=ax_data.transAxes, fontsize=14, verticalalignment='top', bbox=boxprops) # Logos ax_png = fignum.add_subplot(gs[3, 3]) img = mpimg.imread(logoName) plt.axis('off') plt.imshow(img) else: # Logos ax_png = fignum.add_subplot(gs[3, 2:]) img = mpimg.imread(logoName) plt.axis('off') plt.imshow(img) plt.show(block=False) return
skew.ax.set_xlim(-40, 60) # Plot LCL as black dot skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Plot the parcel profile as a black line skew.plot(p, parcel_prof, 'k', linewidth=2) # Shade areas of CAPE and CIN skew.shade_cin(p, T, parcel_prof) skew.shade_cape(p, T, parcel_prof) # Plot a zero degree isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph # Create an inset axes object that is 40% width and height of the # figure and put it in the upper right hand corner. ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, np.hypot(u, v)) # Plot a line colored by wind speed # Show the plot plt.show()
def skewt_plot(p, tc, tdc, t0, date, u=None, v=None, fout='sounding.png', latlon='', title='', show=False): """ h: heights p: pressure tc: Temperature [C] tdc: Dew point [C] date: date of the forecast u,v: u,v wind components adapted from: https://geocat-examples.readthedocs.io/en/latest/gallery/Skew-T/NCL_skewt_3_2.html#sphx-glr-gallery-skew-t-ncl-skewt-3-2-py """ Pmax = 150 # XXX upper limit print('Checking units') if p.attrs['units'] != 'hPa': print('P wrong units') exit() if tc.attrs['units'] != 'degC': print('Tc wrong units') exit() if tdc.attrs['units'] != 'degC': print('Tdc wrong units') exit() if t0.attrs['units'] != 'degC': print('T0 wrong units') exit() if type(u) != type(None) and type(v) != type(None): if u.attrs['units'] != 'm s-1': print('Wind wrong units') exit() LG.info('Inside skewt plot') p = p.values tc = tc.values tdc = tdc.values t0 = t0.mean().values u = u.values * 3.6 # km/h v = v.values * 3.6 # km/h # Grid plot LG.info('creating figure') fig = plt.figure(figsize=(11, 12)) LG.info('created figure') LG.info('creating axis') gs = gridspec.GridSpec(1, 2, width_ratios=[4, 1]) fig.subplots_adjust(wspace=0., hspace=0.) # ax1 = plt.subplot(gs[1:-1,0]) # Adding the "rotation" kwarg will over-ride the default MetPy rotation of # 30 degrees for the 45 degree default found in NCL Skew-T plots LG.info('created axis') LG.info('Creatin SkewT') skew = SkewT(fig, rotation=45, subplot=gs[0, 0]) ax = skew.ax LG.info('Created SkewT') if len(latlon) > 0: ax.text(0, 1, latlon, va='top', ha='left', color='k', fontsize=12, bbox=dict(boxstyle="round", ec=None, fc=(1., 1., 1., 0.9)), zorder=100, transform=ax.transAxes) # Plot the data, T and Tdew vs pressure skew.plot(p, tc, 'C3') skew.plot(p, tdc, 'C0') LG.info('plotted dew point and sounding') # LCL lcl_pressure, lcl_temperature = mpcalc.lcl(p[0] * units.hPa, t0 * units.degC, tdc[0] * units.degC) skew.plot(lcl_pressure, lcl_temperature, 'k.') # Calculate the parcel profile #XXX units workaround parcel_prof = mpcalc.parcel_profile(p * units.hPa, t0 * units.degC, tdc[0] * units.degC).to('degC') # Plot cloud base ind_cross = np.argmin(np.abs(parcel_prof.magnitude - tc)) p_base = np.max([lcl_pressure.magnitude, p[ind_cross]]) t_base = np.max([lcl_temperature.magnitude, tc[ind_cross]]) m_base = mpcalc.pressure_to_height_std(np.array(p_base) * units.hPa) m_base = m_base.to('m').magnitude skew.ax.axhline(p_base, color=(0.5, 0.5, 0.5), ls='--') skew.plot(p_base, t_base, 'C3o', zorder=100) skew.ax.text(t_base, p_base, f'{m_base:.0f}m', ha='left') # Plot the parcel profile as a black line skew.plot(p, parcel_prof, 'k', linewidth=1) LG.info('plotted parcel profile') # shade CAPE and CIN skew.shade_cape(p * units.hPa, tc * units.degC, parcel_prof) skew.shade_cin(p * units.hPa, tc * units.degC, parcel_prof, tdc * units.degC) LG.info('plotted CAPE and CIN') if type(u) != type(None) and type(v) != type(None): LG.info('Plotting wind') ax2 = plt.subplot(gs[0, 1], sharey=ax, zorder=-1) # ax2.yaxis.set_visible(False) ax2.yaxis.tick_right() # ax2.xaxis.tick_top() wspd = np.sqrt(u * u + v * v) ax2.scatter(wspd, p, c=p, cmap=HEIGHTS, zorder=10) gnd = mpcalc.pressure_to_height_std(np.array(p[0]) * units.hPa) gnd = gnd.to('m') # Ground ax2.axhline(p[0], c='k', ls='--') ax2.text(56, p[0], f'{int(gnd.magnitude)}m', horizontalalignment='right') # Techo ax2.axhline(p_base, c=(0.5, 0.5, 0.5), ls='--') ### Background colors ## #for i,c in enumerate(WindSpeed.colors): # rect = Rectangle((i*4, 150), 4, 900, color=c, alpha=0.5,zorder=-1) # ax2.add_patch(rect) ######################### ax2.set_xlim(0, 56) ax2.set_xlabel('Wspeed (km/h)') ax2.grid() def p2h(x): """ x in hPa """ y = mpcalc.pressure_to_height_std(np.array(x) * units.hPa) # y = y.metpy.convert_units('m') y = y.to('m') return y.magnitude def h2p(x): """ x in m """ # x = x.values y = mpcalc.height_to_pressure_std(np.array(x) * units.m) # y = y.metpy.convert_units('hPa') y = y.to('hPa') return y.magnitude # print('------') # print(p[0]) # print('---') # print(p2h(p[0])) # print('---') # print(h2p(p2h(p[0]))) # print('------') # exit() ax2y = ax2.secondary_yaxis(1.02, functions=(p2h, h2p)) ax2y.set_ylabel('height (m)') # ax2y.set_yticks(np.array([1000,2000,3000,4000,6000,6000,10000])) # XXX Not working ax2y.yaxis.set_major_formatter(ScalarFormatter()) ax2y.yaxis.set_minor_formatter(ScalarFormatter()) ################# ax2y.set_color('red') ax2y.tick_params(colors='red', size=7, width=1, which='both') # 'both' refers to minor and major axes # ax2y.set_yticks([1,2,3,4]) #ax2.set_xticks([0,5,10,15,20,30,40,50]) #ax2.set_xticklabels(['0','','10','','20','30','40','50']) ax2.set_xticks([0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 56]) ax2.set_xticklabels( ['0', '', '8', '', '16', '', '24', '32', '40', '48', '56'], fontsize=11, va='center') plt.setp(ax2.get_yticklabels(), visible=False) # Hodograph ax_hod = inset_axes(ax2, '110%', '30%', loc=1) ax_hod.set_yticklabels([]) ax_hod.set_xticklabels([]) L = 80 ax_hod.text(0, L - 5, 'N', horizontalalignment='center', verticalalignment='center') ax_hod.text(L - 5, 0, 'E', horizontalalignment='center', verticalalignment='center') ax_hod.text(-(L - 5), 0, 'W', horizontalalignment='center', verticalalignment='center') ax_hod.text(0, -(L - 5), 'S', horizontalalignment='center', verticalalignment='center') h = Hodograph(ax_hod, component_range=L) h.add_grid(increment=20) h.plot_colormapped( -u, -v, p, cmap=HEIGHTS ) #'viridis_r') # Plot a line colored by pressure (altitude) LG.info('Plotted wind') # # print('=-=-=-=-=-=-=') # # print(ax2.get_yscale()) # # print(ax2y.get_yscale()) # # print('=-=-=-=-=-=-=') # # ax2y.yaxis.tick_right() # # # ax2y.set_ylim(*reversed(ax.get_ylim())) # # ax2y.set_ylim(*ax.get_ylim()) # # # calc pressure to height # # locs = ax2.get_yticks() # # labels = [mpcalc.pressure_to_height_std(h*units.hPa) for h in locs] # # labels = [round(l.to('m'),1) for l in labels] # # for xp,xh in zip(locs,labels): # # print(xp,xh) # # ax2y.set_yticks(locs) # # ax2y.set_yticklabels([f'{int(l.magnitude)}' for l in labels]) # Plot only every n windbarb n = 4 inds, = np.where(p > Pmax) break_p = 25 inds_low = inds[:break_p] inds_high = inds[break_p:] inds = np.append(inds_low[::n], inds_high) skew.plot_barbs( pressure=p[inds], #[::n], # * units.hPa, u=u[inds], #[::n], v=v[inds], #[::n], xloc=0.985, # fill_empty=True, sizes=dict(emptybarb=0.075, width=0.1, height=0.2)) # # # Draw line underneath wind barbs # # line = mlines.Line2D([1.05, 1.05], [0, 1], color='gray', linewidth=0.5, # # transform=ax.transAxes, # # dash_joinstyle='round', # # clip_on=False, # # zorder=0) # # ax.add_line(line) # Add relevant special lines # Choose starting temperatures in Kelvin for the dry adiabats LG.info('Plot adiabats, and other grid lines') skew.ax.text(t0, p[0], f'{t0:.1f}°C', va='top') skew.ax.axvline(t0, color=(0.5, 0.5, 0.5), ls='--') t0 = units.K * np.arange(243.15, 473.15, 10) skew.plot_dry_adiabats(t0=t0, linestyles='solid', colors='gray', linewidth=1) # Choose temperatures for moist adiabats t0 = units.K * np.arange(281.15, 306.15, 4) msa = skew.plot_moist_adiabats(t0=t0, linestyles='solid', colors='lime', linewidths=.75) # Choose mixing ratios w = np.array([0.001, 0.002, 0.003, 0.005, 0.008, 0.012, 0.020]).reshape(-1, 1) # Choose the range of pressures that the mixing ratio lines are drawn over p_levs = units.hPa * np.linspace(1000, 400, 7) skew.plot_mixing_lines(mixing_ratio=w, pressure=p_levs, linestyle='dotted', linewidths=1, colors='lime') LG.info('Plotted adiabats, and other grid lines') skew.ax.set_ylim(1000, Pmax) skew.ax.set_xlim(-20, 43) # skew.ax.set_xlim(-30, 40) # XXX gvutil not installed # gvutil.set_titles_and_labels(ax, maintitle="ATS Rawinsonde: degC + Thin wind") # Set axes limits and ticks # gvutil.set_axes_limits_and_ticks(ax=ax, xlim=[-30, 50], # yticks=[1000, 850, 700, 500, 400, 300, 250, 200, 150, 100]) # Change the style of the gridlines ax.grid(True, which='major', axis='both', color='tan', linewidth=1.5, alpha=0.5) ax.set_xlabel("Temperature (C)") ax.set_ylabel("P (hPa)") if len(title) == 0: title = f"{(date).strftime('%d/%m/%Y-%H:%M')} (local time)" ax.set_title(title, fontsize=20) else: ax.set_title(title, fontsize=20) if show: plt.show() LG.info('saving') fig.savefig(fout, bbox_inches='tight', pad_inches=0.1, dpi=150, quality=90) LG.info('saved') plt.close('all')
# Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(9, 9)) add_metpy_logo(fig, 115, 100) # Grid for plots skew = SkewT(fig, rotation=45) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') skew.plot_barbs(p, u, v) skew.ax.set_ylim(1000, 100) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Good bounds for aspect ratio skew.ax.set_xlim(-50, 60) # Create a hodograph ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, np.hypot(u, v)) # Show the plot plt.show()
skew.ax.set_xlim(-40, 60) # Plot LCL as black dot skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Plot the parcel profile as a black line skew.plot(p, parcel_prof, 'k', linewidth=2) # Shade areas of CAPE and CIN skew.shade_cin(p, T, parcel_prof) skew.shade_cape(p, T, parcel_prof) # Plot a zero degree isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph # Create an inset axes object that is 40% width and height of the # figure and put it in the upper right hand corner. ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, wind_speed) # Plot a line colored by wind speed # Show the plot plt.show()
def plot_upper_air(station='11035', date=False): ''' ----------------------------- Default use of plot_upper_air: This will plot a SkewT sounding for station '11035' (Wien Hohe Warte) plot_upper_air(station='11035', date=False) ''' # sns.set(rc={'axes.facecolor':'#343837', 'figure.facecolor':'#343837', # 'grid.linestyle':'','axes.labelcolor':'#04d8b2','text.color':'#04d8b2', # 'xtick.color':'#04d8b2','ytick.color':'#04d8b2'}) # Get time in UTC station = str(station) if date is False: now = datetime.utcnow() # If morning then 0z sounding, otherwise 12z if now.hour < 12: hour = 0 else: hour = 12 date = datetime(now.year, now.month, now.day, hour) datestr = date.strftime('%Hz %Y-%m-%d') print('{}'.format(date)) else: year = int(input('Please specify the year: ')) month = int(input('Please specify the month: ')) day = int(input('Please specify the day: ')) hour = int(input('Please specify the hour: ')) if hour < 12: hour = 0 else: hour = 12 date = datetime(year, month, day, hour) datestr = date.strftime('%Hz %Y-%m-%d') print('You entered {}'.format(date)) # This requests the data 11035 is df = WyomingUpperAir.request_data(date, station) # Create single variables wih the right units p = df['pressure'].values * units.hPa T = df['temperature'].values * units.degC Td = df['dewpoint'].values * units.degC wind_speed = df['speed'].values * units.knots wind_dir = df['direction'].values * units.degrees wind_speed_6k = df['speed'][df.height <= 6000].values * units.knots wind_dir_6k = df['direction'][df.height <= 6000].values * units.degrees u, v = mpcalc.get_wind_components(wind_speed, wind_dir) u6, v6 = mpcalc.get_wind_components(wind_speed_6k, wind_dir_6k) # Calculate the LCL lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) print(lcl_pressure, lcl_temperature) # Calculate the parcel profile. parcel_prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') cape, cin = mpcalc.cape_cin(p, T, Td, parcel_prof) ############################# # Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(9, 9)) gs = gridspec.GridSpec(3, 3) skew = SkewT(fig, rotation=45, subplot=gs[:, :2]) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') skew.plot_barbs(p, u, v) skew.ax.set_ylim(1000, 100) skew.ax.set_xlim(-45, 40) # Plot LCL as black dot skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Plot the parcel profile as a black line skew.plot(p, parcel_prof, 'k', linewidth=2) # Shade areas of CAPE and CIN skew.shade_cin(p, T, parcel_prof) skew.shade_cape(p, T, parcel_prof) # Plot a zero degree isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) skew.ax.set_title('Station: ' + str(station) + '\n' + datestr) # set title skew.ax.set_xlabel('Temperature (C)') skew.ax.set_ylabel('Pressure (hPa)') # Add the relevant special lines skew.plot_dry_adiabats(linewidth=0.7) skew.plot_moist_adiabats(linewidth=0.7) skew.plot_mixing_lines(linewidth=0.7) # Create a hodograph # Create an inset axes object that is 40% width and height of the # figure and put it in the upper right hand corner. # ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) ax = fig.add_subplot(gs[0, -1]) h = Hodograph(ax, component_range=60.) h.add_grid(increment=20) # Plot a line colored by windspeed h.plot_colormapped(u6, v6, wind_speed_6k) # add another subplot for the text of the indices # ax_t = fig.add_subplot(gs[1:,2]) skew2 = SkewT(fig, rotation=0, subplot=gs[1:, 2]) skew2.plot(p, T, 'r') skew2.plot(p, Td, 'g') # skew2.plot_barbs(p, u, v) skew2.ax.set_ylim(1000, 700) skew2.ax.set_xlim(-30, 10) # Show the plot plt.show() return cape
def process_skewt(self): # Calculation index_p100 = get_pressure_level_index(self.p_i, 100) lcl_p, lcl_t = mpcalc.lcl(self.p_i[0], self.t_i[0], self.td_i[0]) lfc_p, lfc_t = mpcalc.lfc(self.p_i, self.t_i, self.td_i) el_p, el_t = mpcalc.el(self.p_i, self.t_i, self.td_i) prof = mpcalc.parcel_profile(self.p_i, self.t_i[0], self.td_i[0]).to('degC') cape, cin = mpcalc.cape_cin(self.p_i, self.t_i, self.td_i, prof) mucape, mucin = mpcalc.most_unstable_cape_cin(self.p_i, self.t_i, self.td_i) pwat = mpcalc.precipitable_water(self.td_i, self.p_i) i8 = get_pressure_level_index(self.p_i, 850) i7 = get_pressure_level_index(self.p_i, 700) i5 = get_pressure_level_index(self.p_i, 500) theta850 = mpcalc.equivalent_potential_temperature(850 * units('hPa'), self.t_i[i8], self.td_i[i5]) theta500 = mpcalc.equivalent_potential_temperature(500 * units('hPa'), self.t_i[i5], self.td_i[i5]) thetadiff = theta850 - theta500 k = self.t_i[i8] - self.t_i[i5] + self.td_i[i8] - (self.t_i[i7] - self.td_i[i7]) a = ((self.t_i[i8] - self.t_i[i5]) - (self.t_i[i8] - self.td_i[i5]) - (self.t_i[i7] - self.td_i[i7]) - (self.t_i[i5] - self.td_i[i5])) sw = c_sweat(np.array(self.t_i[i8].magnitude), np.array(self.td_i[i8].magnitude), np.array(self.t_i[i5].magnitude), np.array(self.u_i[i8].magnitude), np.array(self.v_i[i8].magnitude), np.array(self.u_i[i5].magnitude), np.array(self.v_i[i5].magnitude)) si = showalter_index(self.t_i[i8], self.td_i[i8], self.t_i[i5]) li = lifted_index(self.t_i[0], self.td_i[0], self.p_i[0], self.t_i[i5]) srh_pos, srh_neg, srh_tot = mpcalc.storm_relative_helicity(self.u_i, self.v_i, self.alt, 1000 * units('m')) sbcape, sbcin = mpcalc.surface_based_cape_cin(self.p_i, self.t_i, self.td_i) shr6km = mpcalc.bulk_shear(self.p_i, self.u_i, self.v_i, heights=self.alt, depth=6000 * units('m')) wshr6km = mpcalc.wind_speed(*shr6km) sigtor = mpcalc.significant_tornado(sbcape, delta_height(self.p_i[0], lcl_p), srh_tot, wshr6km)[0] # Plotting self.ax.set_ylim(1050, 100) self.ax.set_xlim(-40, 50) self.plot(self.p_i, self.t_i, 'r', linewidth=1) self.plot(self.p_i[:self.dp_idx], self.td_i[:self.dp_idx], 'g', linewidth=1) self.plot_barbs(self.p_i[:index_p100], self.u_i[:index_p100] * 1.94, self.v_i[:index_p100] * 1.94) self.plot(lcl_p, lcl_t, 'ko', markerfacecolor='black') self.plot(self.p_i, prof, 'k', linewidth=2) if cin.magnitude < 0: chi = -1 * cin.magnitude self.shade_cin(self.p_i, self.t_i, prof) elif cin.magnitude > 0: chi = cin.magnitude self.shade_cin(self.p_i, self.t_i, prof) else: chi = 0. self.shade_cape(self.p_i, self.t_i, prof) self.plot_dry_adiabats(linewidth=0.5) self.plot_moist_adiabats(linewidth=0.5) self.plot_mixing_lines(linewidth=0.5) plt.title('Skew-T Plot \nStation: {} Time: {}'.format(self.st, self.time.strftime('%Y.%m.%d %H:%M')), fontsize=14, loc='left') # Add hodograph ax = self._fig.add_axes([0.95, 0.71, 0.17, 0.17]) h = Hodograph(ax, component_range=50) h.add_grid(increment=20) h.plot_colormapped(self.u_i[:index_p100], self.v_i[:index_p100], self.alt[:index_p100], linewidth=1.2) # Annotate parameters # Annotate names namelist = ['CAPE', 'CIN', 'MUCAPE', 'PWAT', 'K', 'A', 'SWEAT', 'LCL', 'LFC', 'EL', 'SI', 'LI', 'T850-500', 'θse850-500', 'SRH', 'STP'] xcor = -50 ycor = -90 spacing = -9 for nm in namelist: ax.text(xcor, ycor, '{}: '.format(nm), fontsize=10) ycor += spacing # Annotate values varlist = [cape, chi, mucape, pwat, k, a, sw, lcl_p, lfc_p, el_p, si, li, self.t_i[i8] - self.t_i[i5], thetadiff, srh_tot, sigtor] xcor = 10 ycor = -90 for v in varlist: if hasattr(v, 'magnitude'): v = v.magnitude ax.text(xcor, ycor, str(np.round_(v, 2)), fontsize=10) ycor += spacing # Annotate units unitlist = ['J/kg', 'J/kg', 'J/kg', 'mm', '°C', '°C', '', 'hPa', 'hPa', 'hPa', '°C', '°C', '°C', '°C'] xcor = 45 ycor = -90 for u in unitlist: ax.text(xcor, ycor, ' {}'.format(u), fontsize=10) ycor += spacing
def main(): args = get_args() setup_logging(args['verbose']) # Define input file file = args['inputfile'] output = args['outputfile'] ds = xr.open_dataset(file) ds_sel = ds.isel({'sounding': 0}) ds_sel = ds_sel.sortby(ds_sel.pressure, ascending=False) p = ds_sel.pressure.values T = ds_sel.temperature.values Td = ds_sel.dewPoint.values wind_speed = ds_sel.windSpeed.values wind_dir = ds_sel.windDirection.values # Filter nans idx = np.where((np.isnan(T) + np.isnan(Td) + np.isnan(p) + np.isnan(wind_speed) + np.isnan(wind_dir)) == False, True, False) p = p[idx] T = T[idx] Td = Td[idx] wind_speed = wind_speed[idx] wind_dir = wind_dir[idx] # Add units p = p * units.hPa T = T * units.degC Td = Td * units.degC wind_speed = wind_speed * (units.meter / units.second) wind_dir = wind_dir * units.degrees u, v = mpcalc.wind_components(wind_speed, wind_dir) lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) parcel_prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') # Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(9, 10)) skew = SkewT(fig, rotation=30) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') # Plot only specific barbs to increase visibility pressure_levels_barbs = np.logspace(0.1, 1, 50) * 100 def find_nearest(array, value): array = np.asarray(array) idx = (np.abs(array - value)).argmin() return array[idx] # Search for levels by providing pressures # (levels is the coordinate not pressure) pres_vals = ds_sel.pressure.values[idx] closest_pressure_levels = np.unique( [find_nearest(pres_vals, p_) for p_ in pressure_levels_barbs]) _, closest_pressure_levels_idx, _ = np.intersect1d(pres_vals, closest_pressure_levels, return_indices=True) p_barbs = ds_sel.pressure.isel({ 'levels': closest_pressure_levels_idx }).values * units.hPa wind_speed_barbs = ds_sel.windSpeed.isel({ 'levels': closest_pressure_levels_idx }).values * (units.meter / units.second) wind_dir_barbs = ds_sel.windDirection.isel({ 'levels': closest_pressure_levels_idx }).values * units.degrees u_barbs, v_barbs = mpcalc.wind_components(wind_speed_barbs, wind_dir_barbs) # Find nans in pressure # p_non_nan_idx = np.where(~np.isnan(pres_vals)) skew.plot_barbs(p_barbs, u_barbs, v_barbs, xloc=1.06) # set axes limits: skew.ax.set_ylim(1020, 100) skew.ax.set_xlim(-50, 40) # Plot LCL as black dot skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Plot the parcel profile as a black line skew.plot(pres_vals, parcel_prof, 'k', linewidth=1.6) # Shade areas of CAPE and CIN skew.shade_cin(pres_vals, T, parcel_prof) skew.shade_cape(pres_vals, T, parcel_prof) # Plot a zero degree isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph # Create an inset axes object that is 40% width and height of the # figure and put it in the upper right hand corner. ax_hod = inset_axes(skew.ax, '35%', '35%', loc=1) h = Hodograph(ax_hod, component_range=75.) h.add_grid(increment=20) h.plot_colormapped(u, v, wind_speed) # Plot a line colored by wind speed # Set title sounding_name = ds_sel.sounding.values sounding_name_str = str(sounding_name.astype('str')) skew.ax.set_title('{sounding}'.format(sounding=sounding_name_str)) if output is None: output = str(os.path.basename(file).split('.')[0]) + '.pdf' logging.info('Write output to {}'.format(output)) plt.savefig(output)
skew.plot(p, prof, 'k', linewidth=2) # Shade areas of CAPE and CIN (only below 500 hPa) skew.shade_cin(p, T, prof) skew.shade_cape(p, T, prof) # An example of a slanted line at constant T -- in this case the 0 # isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() #Enter the appropriate title plt.title('<Enter your title here>', weight='bold', size=20) ##If applicable, you can add a hodograph (say, if you have a severe wx sounding); If not, comment out ax_hod = inset_axes( skew.ax, '25%', '25%', loc=2 ) #Change the 30% to alter size, currently plotting in top left (can change loc) h = Hodograph(ax_hod, component_range=80.) #Change range in windspeeds h.add_grid(increment=20) h.plot_colormapped(u, v, wind_speed) # Show the plot plt.show()
# Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph ax_hod = inset_axes(skew.ax, '30%', '30%', loc=1) h = Hodograph(ax_hod, component_range=30.) 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
# Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(9, 9)) add_metpy_logo(fig, 115, 100) # Grid for plots skew = SkewT(fig, rotation=45) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') skew.plot_barbs(p, u, v) skew.ax.set_ylim(1000, 100) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Good bounds for aspect ratio skew.ax.set_xlim(-50, 60) # Create a hodograph ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, np.hypot(u, v)) # Show the plot plt.show()
def main(): args = get_args() setup_logging(args["verbose"]) # Define input file file = args["inputfile"] output = args["outputfile"] ds = xr.open_dataset(file) ds_sel = ds.isel({"sounding": 0}) ds_sel = ds_sel.sortby(ds_sel.p, ascending=False) attrs = ds_sel.attrs ds_sel = ds_sel.metpy.quantify() p = ds_sel.p T = ds_sel.ta Td = ds_sel.dp wind_speed = ds_sel.wspd wind_dir = ds_sel.wdir ascend_rate = ds_sel.dz launch_time = attrs["time_of_launch_HHmmss"] platform = attrs["platform"] resolution = attrs["resolution"].replace(" ", "") # Filter nans idx = np.where( (np.isnan(T) + np.isnan(Td) + np.isnan(p) + np.isnan(wind_speed) + np.isnan(wind_dir)) is False, True, False, ) p = p[idx].metpy.convert_units("hPa") T = T[idx].metpy.convert_units("degC") Td = Td[idx].metpy.convert_units("degC") wind_speed = wind_speed[idx].metpy.convert_units("meter / second") wind_dir = wind_dir[idx] u, v = mpcalc.wind_components(wind_speed, wind_dir) lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) parcel_prof = mpcalc.parcel_profile(p, T[0], Td[0]) parcel_prof = parcel_prof.metpy.convert_units("degC") direction = find_direction_of_sounding(ascend_rate) # Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(9, 10)) skew = SkewT(fig, rotation=30) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, "r") skew.plot(p, Td, "g") # Plot only specific barbs to increase visibility pressure_levels_barbs = np.logspace(0.1, 1, 50) * 100 def find_nearest(array, value): array = np.asarray(array) idx = (np.abs(array - value)).argmin() return array[idx] # Search for levels by providing pressures # (levels is the coordinate not pressure) pres_vals = p.isel(level=idx) closest_pressure_levels = np.unique( [find_nearest(pres_vals, p_) for p_ in pressure_levels_barbs]) _, closest_pressure_levels_idx, _ = np.intersect1d(pres_vals, closest_pressure_levels, return_indices=True) p_barbs = p.isel({"level": closest_pressure_levels_idx}) wind_speed_barbs = wind_speed.isel({"level": closest_pressure_levels_idx}) wind_dir_barbs = wind_dir.isel({"level": closest_pressure_levels_idx}) u_barbs, v_barbs = mpcalc.wind_components(wind_speed_barbs, wind_dir_barbs) # Find nans in pressure skew.plot_barbs(p_barbs, u_barbs, v_barbs, xloc=1.06) skew.ax.set_ylim(1020, 100) skew.ax.set_xlim(-50, 40) # Plot LCL as black dot skew.plot(lcl_pressure, lcl_temperature, "ko", markerfacecolor="black") # Plot the parcel profile as a black line skew.plot(pres_vals, parcel_prof, "k", linewidth=1.6) # Shade areas of CAPE and CIN skew.shade_cin( pres_vals.metpy.convert_units("hPa").values, T.metpy.convert_units("degC").values, parcel_prof.metpy.convert_units("degC").values, ) skew.shade_cape( pres_vals.metpy.convert_units("hPa").values, T.metpy.convert_units("degC").values, parcel_prof.metpy.convert_units("degC").values, ) # Plot a zero degree isotherm skew.ax.axvline(0, color="c", linestyle="--", linewidth=2) # Add the relevant special lines skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() # Create a hodograph # Create an inset axes object that is 40% width and height of the # figure and put it in the upper right hand corner. ax_hod = inset_axes(skew.ax, "35%", "35%", loc=1) h = Hodograph(ax_hod, component_range=75.0) h.add_grid(increment=20) h.plot_colormapped(u, v, wind_speed) # Plot a line colored by wind speed # Set title sounding_name = ds_sel.sounding.values sounding_name_str = str(sounding_name.astype("str")) skew.ax.set_title("{sounding}_{direction}".format( sounding=sounding_name_str, direction=direction)) if output is None: filename_fmt = "{platform}_SoundingProfile_skew_{launch_time}_{res}.png".format( platform=platform, res=resolution, launch_time=launch_time) # filename_fmt = launch_time.strftime(filename_fmt) output = filename_fmt else: output = output.format(platform=platform, direction=direction, resolution=resolution) # output = launch_time.strftime(output) logging.info("Write output to {}".format(output)) plt.savefig(output)
def _plot_hodograph(self, skew): # Create an array that indicates which layer (10-3, 3-1, 0-1 km) the # wind belongs to. The array, agl, will be set to the height # corresponding to the top of the layer. The resulting array will look # something like this: # # agl = [1.0 1.0 1.0 3.0 3.0 3.0 10.0 10.0 10.0 10.87 ] # # Where the values above 10 km are unchanged, and there are three levels # in each of the 3 layers of interest. # agl = np.copy(self.atmo_profiles.get('gh', {}).get('data')).to('km') # Retrieve the wind data profiles u_wind = self.atmo_profiles.get('u', {}).get('data') v_wind = self.atmo_profiles.get('v', {}).get('data') # Create an inset axes object that is 28% width and height of the # figure and put it in the upper left hand corner. ax = inset_axes(skew.ax, '25%', '25%', loc=2) h = Hodograph(ax, component_range=80.) h.add_grid(increment=20, linewidth=0.5) intervals = [0, 1, 3, 10] * agl.units colors = ['xkcd:salmon', 'xkcd:aquamarine', 'xkcd:navy blue'] line_width = 1.5 # Plot the line colored by height AGL only up to the 10km level lines = h.plot_colormapped( u_wind, v_wind, agl, colors=colors, intervals=intervals, linewidth=line_width, ) # Local function to create a proxy line object for creating a legend on # a LineCollection returned from plot_colormapped. Using lines and # colors from outside scope. def make_proxy(zval, idx=None, **kwargs): color = colors[idx] if idx < len(colors) else lines.cmap(zval - 1) return Line2D([0, 1], [0, 1], color=color, linewidth=line_width, **kwargs) # Make a list of proxies proxies = [ make_proxy(item, idx=i) for i, item in enumerate(intervals.magnitude) ] # Draw the legend ax.legend( proxies[:-1], ['0-1 km', '1-3 km', '3-10 km', ''], fontsize='small', loc='lower left', )
skew.ax.set_xlim(-60, 40) skew.ax.set_ylim(1000, 100) skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.plot_mixing_lines() skew.ax.tick_params(axis='both', which='major', labelsize=15) skew.ax.set_xlabel('') skew.ax.set_ylabel('') #cape_cin #prof = mpcalc.parcel_profile(p, t[0], td[0]).to('degC') #skew.plot(p, prof, 'k', linewidth = 2) #skew.shade_cape(p, t, prof) lat = values[0].XLAT.values lon = values[0].XLONG.values utc = str(values[0].Time.values)[:-10] skew.ax.set_title('LAT : {:.5} | LON : {:.5}\n{}'.format(lat, lon, utc), fontsize=20) #hodograph ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, metpy.calc.wind_speed(u, v)) plt.savefig(f'./SkewT_{utc}.png', bbox_inches='tight') plt.show()
def make_hodograph(): # Get the data date = request.args.get('date') time = request.args.get('time') region = request.args.get('region') station = request.args.get('station') date = datetime.strptime(date, '%Y%m%d') date = datetime(date.year, date.month, date.day, int(time)) df = get_sounding_data(date, region, station) p = df['pressure'].values * units(df.units['pressure']) T = df['temperature'].values * units(df.units['temperature']) Td = df['dewpoint'].values * units(df.units['dewpoint']) u = df['u_wind'].values * units(df.units['u_wind']) v = df['v_wind'].values * units(df.units['v_wind']) # Make the Hodograph # Create a new figure. The dimensions here give a good aspect ratio fig = plt.figure(figsize=(4, 4)) ax_hod = plt.subplot(1, 1, 1) h = Hodograph(ax_hod, component_range=80.) h.add_grid(increment=20) h.plot_colormapped(u, v, np.hypot(u, v)) canvas = FigureCanvas(fig) img = BytesIO() fig.savefig(img) img.seek(0) return send_file(img, mimetype='image/png')