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
Exemple #2
0
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
Exemple #3
0
def test_hodograph_wind_vectors():
    """Test plotting wind vectors onto a hodograph."""
    u_wind = np.array([-10, -7, 0, 7, 10, 7, 0, -7])
    v_wind = np.array([0, 7, 10, 7, 0, -7, -10, -7])
    fig = plt.figure(figsize=(6, 6))
    ax = fig.add_subplot(1, 1, 1)
    h = Hodograph(ax, component_range=20)
    h.plot(u_wind, v_wind, linewidth=3)
    h.wind_vectors(u_wind, v_wind)
    return fig
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
    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 = 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)')

# Map - Oklahoma
llcrnrlat = 33.6
urcrnrlat = 37.2
llcrnrlon = -103.2
urcrnrlon = -94.2
ax_map = fig5.add_subplot(gs[2, 2:])

m = Basemap(projection='merc',
            llcrnrlat=llcrnrlat,
Exemple #9
0
def test_hodograph_alone():
    """Test to create Hodograph without specifying axes."""
    Hodograph()
Exemple #10
0
# Create a new figure. The dimensions here give a good aspect ratio
fig = plt.figure(figsize=(9, 9))

# 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()
Exemple #11
0
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_skewt(snd: Sounding, save_to: Optional[str] = None, p_top: int = 100):
    """
    Plots a skew-T from the given Sounding.
    :param snd: The Sounding.
    :param save_to: Where to save the figure.  Default None, which does not save the figure, and instead shows it.
    :param p_top: Pressure at the top of the skew-T.  If you change this, Metpy might change the rotation of the
    isotherms.  No known fix yet.
    :return: None.
    """
    ####################################################################################################################
    # Data extraction and masking

    # Extract data from sounding.
    p = snd.p
    T = snd.T
    Td = snd.Td
    Tw = snd.Tw
    Te = snd.thetaE
    z = snd.z
    cf = snd["CFRL"]
    omega = snd.omega
    u, v = snd.wind_components()

    e = mpcalc.saturation_vapor_pressure(T)
    rv = mpcalc.mixing_ratio(e, p)
    w = mpcalc.vertical_velocity(omega, p, T, rv).to("cm/s")

    # Create masks to filter what data is plotted.
    mask_dewpoint = Td > -9000. * units.degC  # Plot only non-missing dewpoints.
    mask_wetbulb = Tw > -9000. * units.degC  # Plot only non-missing dewpoints.
    mask_thetae = Te > 0. * units.K  # Plot only non-missing theta-es.
    mask_barbs = p > p_top * units.hPa  # Plot only winds below the top of the sounding.

    ####################################################################################################################
    # Define intervals of height for coloring barbs and hodograph.
    z_interval_levels = [1500, 3000, 6000, 9000, 12000, 99999]
    z_interval_colors = ["red", "orange", "green", "blue", "purple", "grey"]

    z_colors = []

    for item in z:
        for color, interval in zip(z_interval_colors, z_interval_levels):
            if item <= interval * units.meter:
                z_colors.append(color)
                break

    ####################################################################################################################
    # Plotting skew-T

    fig = plt.figure(figsize=(11, 11))
    ax_hodo = fig.add_axes([0.70, 0.675, 0.25, 0.25])
    ax_thte = fig.add_axes([0.70, 0.375, 0.25, 0.25])
    skew = SkewT(fig, rotation=45, rect=[0.05, 0.05, 0.60, 0.9])

    # Plot temperature, dewpoint, and wet-bulb.
    skew.plot(p, T, 'r')
    skew.plot(p[mask_dewpoint], Td[mask_dewpoint], 'g')
    skew.plot(p[mask_wetbulb], Tw[mask_wetbulb], color='#009999', linewidth=1)

    # Calculate and plot surface parcel trace.
    sfc_trace = snd.parcel_trace(0).to('degC')
    sfc_trace_plot = skew.plot(p,
                               sfc_trace,
                               c='orange',
                               linewidth=2,
                               zorder=-10)

    # Calculate and plot MU parcel trace.
    mu_level_index = np.argmax(Te[p > 750. * units.hPa])
    mu_trace = snd.parcel_trace(mu_level_index).to('degC')
    mu_trace_plot = skew.plot(p[mu_level_index:],
                              mu_trace,
                              c='gray',
                              linewidth=2,
                              zorder=-9)

    # Plot each barb individually for control over color.  Unfortunately, the c arg of plot_barbs doesn't work for this
    # purpose.
    for p_, u_, v_, c_ in zip(p[mask_barbs][::BARB_DENSITY],
                              u[mask_barbs][::BARB_DENSITY],
                              v[mask_barbs][::BARB_DENSITY],
                              np.array(z_colors)[mask_barbs][::BARB_DENSITY]):
        skew.plot_barbs(p_, u_, v_, y_clip_radius=0.03, barbcolor=c_)

    ####################################################################################################################
    # Cloud fraction and omega
    zero_line = 1 / 15
    cf_plot = (cf * zero_line) / 100
    w_plot = (w.magnitude / 20) + zero_line
    skew.ax.plot(np.zeros(cf_plot.shape) + 1 / 15,
                 snd.p,
                 transform=skew.ax.get_yaxis_transform(),
                 color="grey")
    skew.ax.plot(cf_plot,
                 snd.p,
                 transform=skew.ax.get_yaxis_transform(),
                 color="black")
    skew.ax.plot(w_plot,
                 snd.p,
                 transform=skew.ax.get_yaxis_transform(),
                 color="purple")

    skew.ax.text(np.max(w_plot),
                 snd.p[np.argmax(w_plot)],
                 " {:.1f}".format(np.max(w.magnitude)),
                 color="purple",
                 ha="left",
                 va="center",
                 transform=skew.ax.get_yaxis_transform())
    skew.ax.text(max(np.min(w_plot), 0),
                 snd.p[np.argmin(w_plot)],
                 " {:.1f}".format(np.min(w.magnitude)),
                 color="purple",
                 ha="left",
                 va="center",
                 transform=skew.ax.get_yaxis_transform())
    # skew.ax.fill_betweenx(snd.p, cloud_fractions, np.zeros(cloud_fractions.shape))

    ####################################################################################################################
    # Tweaking

    skew.ax.set_xlim(-30, 40)
    skew.ax.set_ylim(1020, p_top)
    skew.ax.set_xlabel("")
    skew.ax.set_ylabel("")

    # Add legend for the parcel traces.
    skew.ax.legend(handles=[
        mlines.Line2D([], [], color='orange', label='Surface parcel'),
        mlines.Line2D([], [],
                      color='gray',
                      label=r"Max $\theta_e$ below 750mb"),
        mlines.Line2D([], [], color='black', label=r"Cloud fraction"),
        mlines.Line2D([], [],
                      color='purple',
                      label=r"Vertical velocity (cm/s)"),
    ],
                   loc="upper center")

    # Add adiabats and isohumes.
    skew.plot_dry_adiabats(t0=np.arange(233, 533, 10) * units.K,
                           alpha=0.25,
                           color='orangered')
    skew.plot_moist_adiabats(t0=np.arange(233, 400, 5) * units.K,
                             alpha=0.25,
                             color='tab:green')
    # Reshape required as a quirk of metpy.
    skew.plot_mixing_lines(w=np.array(
        [1, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 36]).reshape(-1, 1) / 1000.,
                           p=np.arange(1000, 99, -100) * units.hPa,
                           linestyle='dotted',
                           color='tab:blue')

    plt.title('RAP sounding at {}'.format(snd.params["STID"]), loc='left')
    plt.title('{:.0f}-hour forecast valid at {}'.format(
        snd.params["STIM"], snd.params["TIME"]),
              loc='right')

    ####################################################################################################################
    # Theta-E plot

    # Set up axis for theta-e plot.
    ax_thte.plot(Te[mask_thetae], p[mask_thetae])

    ax_thte.set_xlim(300, 360)
    ax_thte.set_ylim(1020, p_top)
    ax_thte.set_yscale("log")
    ax_thte.set_yticks(np.arange(p_top, 1001, 100))
    ax_thte.set_yticklabels(np.arange(p_top, 1001, 100))
    ax_thte.set_xlabel("")
    ax_thte.grid(axis="both")
    plt.text(0.5,
             0.9,
             "Theta-E (Kelvins)",
             ha="center",
             va="center",
             transform=ax_thte.transAxes)

    ####################################################################################################################
    # Hodograph

    # Set up axis for hodograph.
    h = Hodograph(ax_hodo, component_range=100)
    h.add_grid(20)

    # Plot each segment individually for control over color, reversed so that the full hodograph is plotted first,
    # followed by all but the last segment, etc.  Unfortunately, the plot_colormapped() function doesn't work for this
    # purpose.
    for color, interval in zip(reversed(z_interval_colors),
                               reversed(z_interval_levels)):
        mask = z < interval * units.meter
        h.plot(u.magnitude[mask], v.magnitude[mask], c=color)

    for vector in snd.bunkers_storm_motion():
        h.plot(vector[0], vector[1], c="black", markersize=3, marker="o")

    ax_hodo.set_xticks([])
    ax_hodo.set_yticks([])
    ax_hodo.set_xlim(-60, 100)
    ax_hodo.set_ylim(-60, 100)
    plt.text(0.1,
             0.9,
             "Velocity (knots)",
             ha="left",
             va="center",
             transform=ax_hodo.transAxes)
    for a in range(20, 61, 20):
        ax_hodo.text(-a * 0.71, -a * 0.71, a, ha="center", va="center")

########################################################################################################################
    parameter_names = ["SB STP", "0-1 SRH", "SB CAPE", "SB CIN"]
    parameters = [
        snd.significant_tornado()[0],
        snd.storm_relative_helicity()[2],
        snd.cape_cin(0)[0],
        snd.cape_cin(0)[1]
    ]

    for name, value, i in zip(parameter_names, parameters,
                              range(len(parameters))):
        s = "{:15} {:10.3f}".format(name, value.magnitude)
        fig.text(0.70,
                 0.32 - (0.02 * i),
                 s,
                 ha="left",
                 va="top",
                 family="monospace",
                 transform=fig.transFigure)

########################################################################################################################
    if save_to is None:
        plt.show()
    else:
        plt.savefig(save_to)
        plt.close()
Exemple #13
0
# Create a new figure. The dimensions here give a good aspect ratio
fig = plt.figure(figsize=(9, 9))

# Grid for plots
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)

# 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(-30, 40)

# Create a hodograph
ax = fig.add_subplot(gs[0, -1])
h = Hodograph(ax, component_range=60.)
h.add_grid(increment=20)
h.plot(u, v)

# Show the plot
plt.show()
Exemple #14
0
# 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.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)
Exemple #16
0
    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',
        )
Exemple #17
0
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)
Exemple #18
0
 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
Exemple #19
0
ax2.yaxis.tick_left()
ax2.tick_params(direction='in', pad=-5)

#PLOT PARCEL STUFF
plt.plot((37, 43), (mupcl.lfcpres,mupcl.lfcpres), 'r-',lw=1.5)
ax2.annotate('LFC', xy=(40, mupcl.lfcpres-10), xytext=(40, mupcl.lfcpres-10),ha='center', color='r')
plt.plot((37, 43), (mupcl.lclpres,mupcl.lclpres), 'g-',lw=1.5)
ax2.annotate('LCL', xy=(40, mupcl.lclpres+50), xytext=(40, mupcl.lclpres+50),ha='center', color='g')

# Create windbarbs and hodograph
skew.plot_barbs(p, u, v, xloc=1.1)
hgt_list = [0,3000,6000,9000,np.max(h)]
hodo_color = ['r','g','y','c']
hodo_label = ['0-3km','3-6km','6-9km','>9km']
ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1)
for tick in ax_hod.xaxis.get_major_ticks():
    tick.label.set_fontsize(10)
    tick.label.set_rotation(45)
for tick in ax_hod.yaxis.get_major_ticks():
    tick.label.set_fontsize(10) 
hodo = Hodograph(ax_hod, component_range=80.)
hodo.add_grid(increment=20)
for k in range(len(hgt_list)-1):
    index1 = min(range(len(h)), key=lambda i: abs(h[i]-hgt_list[k]))
    index2 = min(range(len(h)), key=lambda i: abs(h[i]-hgt_list[k+1]))
    hodo.plot(u[index1:index2+1],v[index1:index2+1],c=hodo_color[k],linewidth=2.0,label=hodo_label[k])
ax_hod.legend(loc=2,prop={'size':8})

plt.savefig('/home/kgoebber/http/soundings/launches/'+launch+'_'+ascent+'/'+launch+'_'+ascent+'_KVUM.png',dpi=150)
#plt.show()
Exemple #20
0
skew.plot(p, parcel_prof, 'k', linewidth=3)

# Shade areas of CAPE and CIN
skew.shade_cin(p, T, parcel_prof, Td)
skew.shade_cape(p, T, parcel_prof)

# Plot a zero degree isotherm
skew.ax.axvline(0, color='c', linestyle='--', linewidth=3)

# Add the relevant special lines
skew.plot_dry_adiabats(linewidth=2.5)
skew.plot_moist_adiabats(linewidth=2.5)
skew.plot_mixing_lines(linewidth=2.5)

ax1 = fig.add_subplot(gs[0:7, 4])
h = Hodograph(ax1, component_range=50.)
h.add_grid(increment=12.5)
h.plot(u, v, color='#0080ff')
ax1.tick_params(labelsize=15.)
ax1.set_xticks(np.arange(-50., 75., 25.))
ax1.set_yticks(np.arange(-50., 75., 25.))
ax1.set_xticklabels([])
ax1.set_title('Hodograph', fontsize=20.)
ax1.set_xlabel('wind speed ($m$ $s^{-1}$)', fontsize=15.)
ax1.set_ylabel('wind speed ($m$ $s^{-1}$)', fontsize=15.)

ax2 = fig.add_subplot(gs[9:15, 4])
[ax2.add_patch(PolygonPatch(shape, fc='none')) for shape in shapes]
ax2.scatter(lon[10:], lat[10:], c='r', s=10)
ax2.tick_params(labelsize=15.)
ax2.set_xticks(np.arange(119.5, 122., 0.5))
Exemple #21
0
def test_united_hodograph_range():
    """Tests making a hodograph with a united ranged."""
    fig = plt.figure(figsize=(6, 6))
    ax = fig.add_subplot(1, 1, 1)
    Hodograph(ax, component_range=60. * units.knots)
# 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
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',
Exemple #23
0
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')
Exemple #24
0
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()
Exemple #25
0
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()
Exemple #26
0
#cambiando la direccion cardinal a angular
angle = np.zeros(len(direction) +
                 2)  #añado el dos para igualar size de ambas columnas

#corregir
#cambiar la denominacion: NS por NW

for i in range(2, len(direction) + 2):
    angle[i] = portolan.middle(direction.direccion[i])

#5. GENERACIÓN DE LA HODOGRAFA
angle = pd.DataFrame(angle[2:], columns=['angulo'])

wind_speed = wind.values * units.knots
wind_dir = angle.values * units.degrees

u, v = mpcalc.wind_components(wind_speed, wind_dir)

#visualizando la hodografa
fig = plt.figure(figsize=(6, 6))
fig.suptitle('Hodografa - Estacion 000527')

ax = fig.add_subplot(1, 1, 1)
h = Hodograph(ax, component_range=10.)
h.plot(u, v, linewidth=5)
h.add_grid(increment=5)
plt.savefig(dir_file + '/hodografa.png')

#resultado: dado que la hodografa es casi constante en todo la figura
#concluimos que la velocidad del viento es casi constante en modulo y direccion