Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def test_skewt_api():
    """Test the SkewT API."""
    fig = plt.figure(figsize=(9, 9))
    skew = SkewT(fig)

    # Plot the data using normal plotting functions, in this case using
    # log scaling in Y, as dictated by the typical meteorological plot
    p = np.linspace(1000, 100, 10)
    t = np.linspace(20, -20, 10)
    u = np.linspace(-10, 10, 10)
    skew.plot(p, t, 'r')
    skew.plot_barbs(p, u, u)

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

    return fig
Ejemplo n.º 3
0
def test_skewt_api():
    """Test the SkewT API."""
    with matplotlib.rc_context({'axes.autolimit_mode': 'data'}):
        fig = plt.figure(figsize=(9, 9))
        skew = SkewT(fig)

        # Plot the data using normal plotting functions, in this case using
        # log scaling in Y, as dictated by the typical meteorological plot
        p = np.linspace(1000, 100, 10)
        t = np.linspace(20, -20, 10)
        u = np.linspace(-10, 10, 10)
        skew.plot(p, t, 'r')
        skew.plot_barbs(p, u, u)

        skew.ax.set_xlim(-20, 30)
        skew.ax.set_ylim(1000, 100)

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

    return fig
Ejemplo n.º 4
0
Td = dataset.variables['dewpoint'][:]
u = dataset.variables['u_wind'][:]
v = dataset.variables['v_wind'][:]

###########################################
skew = SkewT()

# 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)

# Add the relevant special lines
skew.plot_dry_adiabats()
skew.plot_moist_adiabats()
skew.plot_mixing_lines()
skew.ax.set_ylim(1000, 100)

###########################################

# Example of defining your own vertical barb spacing
skew = SkewT()

# 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')

# Set spacing interval--Every 50 mb from 1000 to 100 mb
my_interval = np.arange(100, 1000, 50) * units('mbar')
Ejemplo n.º 5
0
def main():
    img_dir = Path("hail_plots/soundings/")

    if not img_dir.exists():
        img_dir.mkdir(parents=True)


    data_dir = Path("/HOME/huziy/skynet3_rech1/hail/soundings_from_erai/")

    # dates = [datetime(1991, 9, 7), datetime(1991, 9, 7, 6), datetime(1991, 9, 7, 12), datetime(1991, 9, 7, 18),
    #          datetime(1991, 9, 8, 0), datetime(1991, 9, 8, 18)]
    #
    # dates.extend([datetime(1991, 9, 6, 0), datetime(1991, 9, 6, 6), datetime(1991, 9, 6, 12), datetime(1991, 9, 6, 18)])
    #
    # dates = [datetime(1990, 7, 7), datetime(2010, 7, 12), datetime(1991, 9, 8, 0)]



    dates_s = """
- 07/09/1991 12:00
- 07/09/1991 18:00
- 08/09/1991 00:00
- 08/09/1991 06:00
- 08/09/1991 12:00
- 13/09/1991 12:00
- 13/09/1991 18:00
- 14/09/1991 00:00
- 14/09/1991 06:00
- 14/09/1991 12:00
    """

    dates = [datetime.strptime(line.strip()[1:].strip(), "%d/%m/%Y %H:%M") for line in dates_s.split("\n") if line.strip() != ""]




    def __date_parser(s):
        return pd.datetime.strptime(s, '%Y-%m-%d %H:%M:%S')


    tt = pd.read_csv(data_dir.joinpath("TT.csv"), index_col=0, parse_dates=['Time'])
    uu = pd.read_csv(data_dir.joinpath("UU.csv"), index_col=0, parse_dates=['Time'])
    vv = pd.read_csv(data_dir.joinpath("VV.csv"), index_col=0, parse_dates=['Time'])
    hu = pd.read_csv(data_dir.joinpath("HU.csv"), index_col=0, parse_dates=['Time'])


    print(tt.head())
    print([c for c in tt])
    print(list(tt.columns.values))




    temp_perturbation_degc = 0

    for the_date in dates:

        p = np.array([float(c) for c in tt])

        fig = plt.figure(figsize=(9, 9))
        skew = SkewT(fig)

        skew.ax.set_ylim(1000, 100)
        skew.ax.set_xlim(-40, 60)


        tsel = tt.select(lambda d: d == the_date)
        usel = uu.select(lambda d: d == the_date)
        vsel = vv.select(lambda d: d == the_date)
        husel = hu.select(lambda d: d == the_date)


        tvals = tsel.values.mean(axis=0)
        uvals = usel.values.mean(axis=0) * mul_mpers_per_knot
        vvals = vsel.values.mean(axis=0) * mul_mpers_per_knot
        huvals = husel.values.mean(axis=0) * units("g/kg")


        # ignore the lowest level
        all_vars = [p, tvals, uvals, vvals, huvals]

        for i in range(len(all_vars)):
            all_vars[i] = all_vars[i][:-5]

        p, tvals, uvals, vvals, huvals = all_vars


        assert len(p) == len(huvals)

        tdvals = calc.dewpoint(calc.vapor_pressure(p * units.mbar, huvals).to(units.mbar))


        print(tvals, tdvals)
        # Calculate full parcel profile and add to plot as black line
        parcel_profile = calc.parcel_profile(p[::-1] * units.mbar, (tvals[-1] + temp_perturbation_degc) * units.degC, tdvals[-1]).to('degC')
        parcel_profile = parcel_profile[::-1]
        skew.plot(p, parcel_profile, 'k', linewidth=2)



        # Example of coloring area between profiles
        greater = tvals * units.degC >= parcel_profile
        skew.ax.fill_betweenx(p, tvals, parcel_profile, where=greater, facecolor='blue', alpha=0.4)
        skew.ax.fill_betweenx(p, tvals, parcel_profile, where=~greater, facecolor='red', alpha=0.4)



        skew.plot(p, tvals, "r")
        skew.plot(p, tdvals, "g")

        skew.plot_barbs(p, uvals, vvals)

        # Plot a zero degree isotherm
        l = 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()

        plt.title("{} (dT={})".format(the_date, temp_perturbation_degc))

        img_path = "{}_dT={}.png".format(the_date.strftime("%Y%m%d_%H%M%S"), temp_perturbation_degc)
        img_path = img_dir.joinpath(img_path)
        fig.savefig(str(img_path), bbox_inches="tight")

        plt.close(fig)
Ejemplo n.º 6
0
def cape(filelist,storm,track,show):
    #Sort filelist.
    filelist=np.sort(filelist)

    # Get sampling periods (this will be a dictionary). See the toolbox
    print('Retrieving sampling periods')
    sampleperiods=getsamplingperiods(filelist,3.)

    # Iterate over all sampling periods.
    for sampindex,periodskey in enumerate(sampleperiods):

        #Allocate starting (stdt) and ending date (endt). Remeber dt is the convetional short-name for date.
        stdt=periodskey
        endt=sampleperiods[periodskey]

        # Define sampling period string
        period=str(stdt.hour)+'_'+str(stdt.day)+'-'+str(endt.hour)+'_'+str(endt.day)

        # Create new-empty lists.
        lats=[]
        lons=[]
        xs=[]
        ys=[]
        capes=[]
        cins=[]
	
        distfig = plt.figure(figsize=(13, 9))
        ax=distfig.add_subplot(111)
        print('start filelist loop')
        # Iterate over all files.
        for filename in filelist:



            # Select end-name of file by inspecting filename string. Notice how filename can change how file is read.
            if 'radazm' in filename.split('/')[-1] or 'eol' in filename.split('/')[-1]:
                end='radazm'
            else:
                end='avp'
            # Obtain properties of file, i.e., launch time and location into a dictionary (dicc).
            dicc=findproperties(filename,end)

            # Condition to see if current file is in sampling period.
            # Notice how if structure is constructed, condition finds times outside of sampling period and
            # if found outside the sampling period, continue to next file.
            if dicc['Launch Time']<stdt or dicc['Launch Time'] > endt:
                continue

            nump=np.genfromtxt(filename,skip_header=16,skip_footer=0)
            temperature=clean1(nump[:,5])
            pressure=clean1(nump[:,4])
            Height=clean1(nump[:,13])
            if np.nanmax(Height)<3500:
                continue
            #Clean for cape
            RelH=clean1(nump[:,7])
            lon=clean1(nump[:,14])
            lat=clean1(nump[:,15])
            lon=clean1(lon)
            lat=clean1(lat)
            mlon=np.nanmean(lon)
            mlat=np.nanmean(lat)
            RH=RelH/100
            T,P,rh,dz=cleanforcape(temperature,pressure,RH,Height)

            #Metpy set-up
            T=np.flip(T,0)
            rh=np.flip(rh,0)
            p=np.flip(P,0)
            dz=np.flip(dz,0)
            p=p*units.hPa
            T=T*units.celsius


            mixing=rh*mpcalc.saturation_mixing_ratio(p,T)
            epsilon=0.6219800858985514
            Tv=mpcalc.virtual_temperature(T, mixing,
                                      molecular_weight_ratio=epsilon)
            dwpoint=mpcalc.dewpoint_rh(T, rh)

            blh_indx=np.where(dz<500)
            try:
                parcelprofile=mpcalc.parcel_profile(p,np.nanmean(T[blh_indx])*units.celsius,mpcalc.dewpoint_rh(np.nanmean(T[blh_indx])*units.celsius, np.nanmean(rh[blh_indx]))).to('degC')
                Tv_parcelprofile=mpcalc.virtual_temperature(parcelprofile, mixing,
                                          molecular_weight_ratio=epsilon)
                cape,cin=cape_cin(p,Tv,dwpoint,Tv_parcelprofile,dz,T)
            except:
                continue

            plotskewT=True
            if plotskewT==True:

                os.system('mkdir figs/skewt')
                fig = plt.figure(figsize=(9, 9))
                skew = SkewT(fig, rotation=45)
                skew.ax.set_ylim(1000, 100)
                skew.ax.set_xlim(-40, 60)

                skew.plot(p, dwpoint, 'g',label=r'$T_{dp}$')
                skew.plot(p, Tv, 'r',label=r'$T_v$')
                plt.text(-120,120,str(np.around(cape,2)),fontsize=14,fontweight='bold')

                # 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,Tv_parcelprofile,'k',label=r'$T_{v env}$')
                skew.shade_cin(p, T, parcelprofile,label='CIN')
                skew.shade_cape(p, Tv, Tv_parcelprofile,label='CAPE')
                skew.plot_dry_adiabats()
                skew.plot_moist_adiabats()

                plt.legend()
                plt.title(storm + ' on' + period,fontsize=14)
                plt.savefig('figs/skewt/'+storm+str(dicc['Launch Time'].time())+'.png')
                #plt.show()
                plt.close()

            r,theta=cart_to_cylindr(mlon,mlat,track,dicc['Launch Time'])
            if not(np.isnan(r)) and not(np.isnan(theta)) and not(np.isnan(cape.magnitude)):
                xs.append(r*np.cos(theta))
                ys.append(r*np.sin(theta))
                capes.append(cape.magnitude)
                cins.append(cin)


            cs=ax.scatter(xs,ys,c=np.asarray(capes),cmap='jet')
            for i,xi in enumerate(xs):
                ax.text(xi,ys[i]+10,str(np.around(capes[i],1)))
        plt.colorbar(cs)
        ax.scatter(0,0,marker='v',s=100,color='black')
        ax.grid()
        ax.set_xlabel('X distance [km]')
        ax.set_ylabel('Y distance [km]')
        ax.set_title('CAPE distribution for '+storm+' on '+period,fontsize=14)
        distfig.savefig('figs/cape'+storm+period+'.png')
        if show:
            plt.show()
Ejemplo n.º 7
0
    # Recreate stack of wind barbs
    s = []
    bot=2000.
    # Space out wind barbs evenly on log axis.
    for ind, i in enumerate(prof.pres):
        if i < 100: break
        if np.log(bot/i) > 0.04:
            s.append(ind)
            bot = i
    b = skew.plot_barbs(prof.pres[s], prof.u[s], prof.v[s], linewidth=0.4, length=6)
    # 'knots' label under wind barb stack
    kts = ax.text(1.0, 0, 'knots', clip_on=False, ha='center',va='bottom',size=7,zorder=2)

    # Tried drawing adiabats and mixing lines right after creating SkewT object but got errors. 
    draw_adiabats  = skew.plot_dry_adiabats(color='r', alpha=0.2, linestyle="solid")
    moist_adiabats = skew.plot_moist_adiabats(linewidth=0.5, color='black', alpha=0.2)
    mixing_lines   = skew.plot_mixing_lines(color='g', alpha=0.35, linestyle="dotted")


    string = "created "+str(datetime.datetime.now(tz=None)).split('.')[0]
    plt.annotate(s=string, xy=(10,2), xycoords='figure pixels', fontsize=5)
        
    res = plt.savefig(ofile,dpi=125)
    skew.ax.clear()
    ax.clear()
    if verbose:
        print 'created', os.path.realpath(ofile)
    mapax.clear()
    hodo_ax.clear()

    # Copy to web server
Ejemplo n.º 8
0
class Window(QtGui.QMainWindow):
    r""" A mainwindow object for the GUI display. Inherits from QMainWindow."""

    def __init__(self):
        super(Window, self).__init__()
        self.interface()

    def interface(self):
        r""" Contains the main window interface generation functionality. Commented where needed."""

        # Get the screen width and height and set the main window to that size
        screen = QtGui.QDesktopWidget().screenGeometry()
        self.setGeometry(0, 0, 800, screen.height())
        self.setMaximumSize(QtCore.QSize(800, 2000))

        # Set the window title and icon
        self.setWindowTitle("WAVE: Weather Analysis and Visualization Environment")
        self.setWindowIcon(QtGui.QIcon('./img/wave_64px.png'))

        # Import the stylesheet for this window and set it to the window
        stylesheet = "css/MainWindow.css"
        with open(stylesheet, "r") as ssh:
            self.setStyleSheet(ssh.read())
        self.setAutoFillBackground(True)
        self.setBackgroundRole(QtGui.QPalette.Highlight)

        # Create actions for menus and toolbar
        exit_action = QtGui.QAction(QtGui.QIcon('./img/exit_64px.png'), 'Exit', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Exit application')
        exit_action.triggered.connect(self.close)
        clear_action = QtGui.QAction(QtGui.QIcon('./img/clear_64px.png'), 'Clear the display', self)
        clear_action.setShortcut('Ctrl+C')
        clear_action.setStatusTip('Clear the display')
        clear_action.triggered.connect(self.clear_canvas)
        skewt_action = QtGui.QAction(QtGui.QIcon('./img/skewt_64px.png'), 'Open the skew-T dialog', self)
        skewt_action.setShortcut('Ctrl+S')
        skewt_action.setStatusTip('Open the skew-T dialog')
        skewt_action.triggered.connect(self.skewt_dialog)
        radar_action = QtGui.QAction(QtGui.QIcon('./img/radar_64px.png'), 'Radar', self)
        radar_action.setShortcut('Ctrl+R')
        radar_action.setStatusTip('Open Radar Dialog Box')
        radar_action.triggered.connect(self.radar_dialog)

        # Create the top menubar, setting native to false (for OS) and add actions to the menus
        menubar = self.menuBar()
        menubar.setNativeMenuBar(False)
        filemenu = menubar.addMenu('&File')
        editmenu = menubar.addMenu('&Edit')
        helpmenu = menubar.addMenu('&Help')
        filemenu.addAction(exit_action)

        # Create the toolbar, place it on the left of the GUI and add actions to toolbar
        left_tb = QtGui.QToolBar()
        self.addToolBar(QtCore.Qt.LeftToolBarArea, left_tb)
        left_tb.setMovable(False)
        left_tb.addAction(clear_action)
        left_tb.addAction(skewt_action)
        left_tb.addAction(radar_action)
        self.setIconSize(QtCore.QSize(30, 30))

        # Create the toolbar, place it on the left of the GUI and add actions to toolbar
        right_tb = QtGui.QToolBar()
        self.addToolBar(QtCore.Qt.RightToolBarArea, right_tb)
        right_tb.setMovable(False)
        right_tb.addAction(clear_action)
        right_tb.addAction(skewt_action)
        right_tb.addAction(radar_action)

        # Create the status bar with a default display
        self.statusBar().showMessage('Ready')

        # Figure and canvas widgets that display the figure in the GUI
        self.figure = plt.figure(facecolor='#2B2B2B')
        self.canvas = FigureCanvas(self.figure)

        # Add subclassed matplotlib navbar to GUI
        # spacer widgets for left and right of buttons
        left_spacer = QtGui.QWidget()
        left_spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        right_spacer = QtGui.QWidget()
        right_spacer.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        self.mpltb = QtGui.QToolBar()
        self.mpltb.addWidget(left_spacer)
        self.mpltb.addWidget(MplToolbar(self.canvas, self))
        self.mpltb.addWidget(right_spacer)
        self.mpltb.setMovable(False)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.mpltb)

        # Set the figure as the central widget and show the GUI
        self.setCentralWidget(self.canvas)
        self.show()

    def skewt_dialog(self):
        r""" When the toolbar icon for the Skew-T dialog is clicked, this function is executed. Creates an instance of
        the SkewTDialog object which is the dialog box. If the submit button on the dialog is clicked, get the user
        inputted values and pass them into the sounding retrieval call (DataAccessor.get_sounding) to fetch the data.
        Finally, plot the returned data via self.plot.

        Args:
            None.
        Returns:
            None.
        Raises:
            None.

        """

        dialog = SkewTDialog()
        if dialog.exec_():
            source, lat, long = dialog.get_values()
            t, td, p, u, v, lat, long, time = DataAccessor.get_sounding(source, lat, long)
            self.plot(t, td, p, u, v, lat, long, time)

    def plot(self, t, td, p, u, v, lat, long, time):
        r"""Displays the Skew-T data on a matplotlib figure.

        Args:
            t (array-like): A list of temperature values.
            td (array-like): A list of dewpoint values.
            p (array-like): A list of pressure values.
            u (array-like): A list of u-wind component values.
            v (array-like): A list of v-wind component values.
            lat (string): A string containing the requested latitude value.
            long (string): A string containing the requested longitude value.
            time (string): A string containing the UTC time requested with seconds truncated.
        Returns:
            None.
        Raises:
            None.

        """

        # Create a new figure. The dimensions here give a good aspect ratio
        self.skew = SkewT(self.figure, rotation=40)

        # Plot the data using normal plotting functions, in this case using
        # log scaling in Y, as dictated by the typical meteorological plot
        self.skew.plot(p, t, 'r')
        self.skew.plot(p, td, 'g')
        self.skew.plot_barbs(p, u, v, barbcolor='#FF0000', flagcolor='#FF0000')
        self.skew.ax.set_ylim(1000, 100)
        self.skew.ax.set_xlim(-40, 60)

        # Axis colors
        self.skew.ax.tick_params(axis='x', colors='#A3A3A4')
        self.skew.ax.tick_params(axis='y', colors='#A3A3A4')

        # Calculate LCL height and plot as black dot
        l = lcl(p[0], t[0], td[0])
        lcl_temp = dry_lapse(concatenate((p[0], l)), t[0])[-1].to('degC')
        self.skew.plot(l, lcl_temp, 'ko', markerfacecolor='black')

        # Calculate full parcel profile and add to plot as black line
        prof = parcel_profile(p, t[0], td[0]).to('degC')
        self.skew.plot(p, prof, 'k', linewidth=2)

        # Color shade areas between profiles
        self.skew.ax.fill_betweenx(p, t, prof, where=t >= prof, facecolor='#5D8C53', alpha=0.7)
        self.skew.ax.fill_betweenx(p, t, prof, where=t < prof, facecolor='#CD6659', alpha=0.7)

        # Add the relevant special lines
        self.skew.plot_dry_adiabats()
        self.skew.plot_moist_adiabats()
        self.skew.plot_mixing_lines()

        # Set title
        deg = u'\N{DEGREE SIGN}'
        self.skew.ax.set_title('Sounding for ' + lat + deg + ', ' + long + deg + ' at ' + time + 'z', y=1.02,
                               color='#A3A3A4')

        # Discards old graph, works poorly though
        # skew.ax.hold(False)
        # Figure and canvas widgets that display the figure in the GUI

        # set canvas size to display Skew-T appropriately
        self.canvas.setMaximumSize(QtCore.QSize(800, 2000))
        # refresh canvas
        self.canvas.draw()

    def radar_dialog(self):
        r""" When the toolbar icon for the Skew-T dialog is clicked, this function is executed. Creates an instance of
        the SkewTDialog object which is the dialog box. If the submit button on the dialog is clicked, get the user
        inputted values and pass them into the sounding retrieval call (DataAccessor.get_sounding) to fetch the data.
        Finally, plot the returned data via self.plot.

        Args:
            None.
        Returns:
            None.
        Raises:
            None.

        """

        radar_dialog = RadarDialog()

        if radar_dialog.exec_():
            station, product = radar_dialog.get_radarvals()
            x, y, ref = DataAccessor.get_radar(station, product)
            self.plot_radar(x, y, ref)

    def plot_radar(self, x, y, ref):
        r"""Displays the Skew-T data on a matplotlib figure.

        Args:
            t (array-like): A list of temperature values.
            td (array-like): A list of dewpoint values.
            p (array-like): A list of pressure values.
            u (array-like): A list of u-wind component values.
            v (array-like): A list of v-wind component values.
            lat (string): A string containing the requested latitude value.
            long (string): A string containing the requested longitude value.
            time (string): A string containing the UTC time requested with seconds truncated.
        Returns:
            None.
        Raises:
            None.

        """

        self.ax = self.figure.add_subplot(111)
        self.ax.pcolormesh(x, y, ref)
        self.ax.set_aspect('equal', 'datalim')
        self.ax.set_xlim(-460, 460)
        self.ax.set_ylim(-460, 460)
        self.ax.tick_params(axis='x', colors='#A3A3A4')
        self.ax.tick_params(axis='y', colors='#A3A3A4')

        # set canvas size to display Skew-T appropriately
        self.canvas.setMaximumSize(QtCore.QSize(800, 2000))
        # refresh canvas
        self.canvas.draw()

    def clear_canvas(self):
        self.canvas.close()
        self.figure = plt.figure(facecolor='#2B2B2B')
        self.canvas = FigureCanvas(self.figure)
        self.setCentralWidget(self.canvas)
Ejemplo n.º 9
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.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, 9))
    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)

    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=2)

    # 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, '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

    # 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)
Ejemplo n.º 10
0
def fmi2skewt(station, time, img_name):

    apikey = 'e72a2917-1e71-4d6f-8f29-ff4abfb8f290'

    url = 'http://data.fmi.fi/fmi-apikey/' + str(
        apikey
    ) + '/wfs?request=getFeature&storedquery_id=fmi::observations::weather::sounding::multipointcoverage&fmisid=' + str(
        station) + '&starttime=' + str(time) + '&endtime=' + str(time) + '&'

    req = requests.get(url)
    xmlstring = req.content
    tree = ET.ElementTree(ET.fromstring(xmlstring))
    root = tree.getroot()

    #reading location and time data to "positions" from XML
    positions = ""
    for elem in root.getiterator(
            tag='{http://www.opengis.net/gmlcov/1.0}positions'):
        positions = elem.text

    #'positions' is string type variable
    #--> split positions into a list by " "
    #then remove empty chars and "\n"
    # from pos_split --> data into positions_data

    try:
        pos_split = positions.split(' ')
    except NameError:
        return "Sounding data not found: stationid " + station + " time " + time

    pos_split = positions.split(' ')

    positions_data = []
    for i in range(0, len(pos_split)):
        if not (pos_split[i] == "" or pos_split[i] == "\n"):
            positions_data.append(pos_split[i])

    #index for height: 2,6,10 etc in positions_data
    height = []
    myList = range(2, len(positions_data))
    for i in myList[::4]:
        height.append(positions_data[i])

    p = []
    for i in range(0, len(height)):
        p.append(height2pressure(float(height[i])))

    #reading wind speed, wind direction, air temperature and dew point data to 'values'
    values = ""
    for elem in root.getiterator(
            tag='{http://www.opengis.net/gml/3.2}doubleOrNilReasonTupleList'):
        values = elem.text

    #split 'values' into a list by " "
    #then remove empty chars and "\n"

    val_split = values.split(' ')
    values_data = []
    for i in range(0, len(val_split)):
        if not (val_split[i] == "" or val_split[i] == "\n"):
            values_data.append(val_split[i])

    #data in values_data: w_speed, w_dir, t_air, t_dew
    wind_speed = []
    wind_dir = []
    T = []
    Td = []
    myList = range(0, len(values_data))
    for i in myList[::4]:
        wind_speed.append(float(values_data[i]))
        wind_dir.append(float(values_data[i + 1]))
        T.append(float(values_data[i + 2]))
        Td.append(float(values_data[i + 3]))

    if stationid == "101104":
        loc_time = "Jokioinen Ilmala " + time1
    elif stationid == "101932":
        loc_time = "Sodankyla Tahtela " + time1
    else:
        return None

    #calculate wind components u,v:
    u = []
    v = []
    for i in range(0, len(wind_speed)):
        u1, v1 = getWindComponent(wind_speed[i], wind_dir[i])
        u.append(u1)
        v.append(v1)

    #find index for pressure < 100hPa (for number of wind bars)
    if min(p) > 100:
        wthin = len(p) / 20
        u_plot = u
        v_plot = v
        p_plot = p
    else:
        for i in range(0, len(p)):
            if p[i] - 100 <= 0:
                wthin = i / 20
                u_plot = u[0:i]
                v_plot = v[0:i]
                p_plot = p[0:i]
                break

    #units
    wind_speed = wind_speed * units("m/s")
    wind_dir = wind_dir * units.deg
    T = T * units.degC
    Td = Td * units.degC
    p = p * units("hPa")

    #calculate pwat, lcl, cape, cin and plot cape
    pwat = mpcalc.precipitable_water(Td, p, bottom=None, top=None)
    lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0])
    prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC')

    try:
        cape, cin = mpcalc.cape_cin(p, T, Td, prof)
    except IndexError:
        cape = 0 * units("J/kg")
        cin = 0 * units("J/kg")

    #__________________plotting__________________
    fig = plt.figure(figsize=(9, 9))
    skew = SkewT(fig, rotation=45)
    font_par = {
        'family': 'monospace',
        'color': 'darkred',
        'weight': 'normal',
        'size': 10,
    }
    font_title = {
        'family': 'monospace',
        'color': 'black',
        'weight': 'normal',
        'size': 20,
    }
    font_axis = {
        'family': 'monospace',
        'color': 'black',
        'weight': 'normal',
        'size': 10,
    }
    # 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, 'k')
    skew.plot(p, Td, 'b')
    skew.ax.set_ylim(1000, 100)
    skew.ax.set_xlim(-40, 60)
    skew.plot_barbs(p_plot[0::wthin], u_plot[0::wthin], v_plot[0::wthin])
    skew.plot_dry_adiabats(alpha=0.4)
    skew.plot_moist_adiabats(alpha=0.4)
    skew.plot_mixing_lines(alpha=0.4)
    skew.shade_cape(p, T, prof, color="orangered")
    plt.title(loc_time, fontdict=font_title)
    plt.xlabel("T (C)", fontdict=font_axis)
    plt.ylabel("P (hPa)", fontdict=font_axis)

    #round and remove units from cape,cin,plcl,tlcl,pwat
    if cape.magnitude > 0:
        capestr = str(np.round(cape.magnitude))
    else:
        capestr = "NaN"

    if cin.magnitude > 0:
        cinstr = str(np.round(cin.magnitude))
    else:
        cinstr = "NaN"

    lclpstr = str(np.round(lcl_pressure.magnitude))
    lclTstr = str(np.round(lcl_temperature.magnitude))
    pwatstr = str(np.round(pwat.magnitude))

    str_par = "CAPE[J/kg]=" + capestr + " CIN[J/kg]=" + cinstr + " Plcl[hPa]=" + lclpstr + " Tlcl[C]=" + lclTstr + " pwat[mm]=" + pwatstr
    font = {
        'family': 'monospace',
        'color': 'darkred',
        'weight': 'normal',
        'size': 10,
    }
    plt.text(-20, 1250, str_par, fontdict=font_par)
    save_file = "figures/" + img_name + ".png"
    plt.savefig(save_file)
Ejemplo n.º 11
0
    # An example of a slanted line at constant T -- in this case the 0
    # isotherm
    skew.ax.axvline(0, color='c', linestyle='-', linewidth=1)
    for i in range(23):
        for j in range(2, 9, 2):
            skew.ax.axvline(i * 10 - 160 + j,
                            color='c',
                            linestyle='--',
                            linewidth=0.3)
            #print (i*10-40+j)

    # Add the relevant special lines
    skew.plot_dry_adiabats(color='green', linestyle='-')
    #skew.plot_dry_adiabats([1, 2], color='green', linestyle='-', linewidth=1)
    skew.plot_moist_adiabats(color='brown', linestyle='-')
    skew.plot_mixing_lines(color='blue', linestyle='--', linewidth=0.3)

    fig.savefig('{0}student_{1}.png'.format(dir_name, selected_time[:13]),
                dpi=None,
                facecolor='w',
                edgecolor='w',
                orientation='portrait',
                papertype=None,
                format=None,
                transparent=False,
                bbox_inches=None,
                pad_inches=0.1,
                frameon=None,
                metadata=None)
# 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[::3], u[::3], v[::3], y_clip_radius=0.03)

# Set some appropriate axes limits for x and y
skew.ax.set_xlim(-30, 40)
skew.ax.set_ylim(1020, 100)

# Add the relevant special lines to plot throughout the figure
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')

# does not work for me, unclear why:
# skew.plot_mixing_lines(p=np.arange(1000, 99, -20) * units.hPa,
#                         linestyle='dotted', color='tab:blue')
# this does:
skew.plot_mixing_lines(linestyle='dotted', color='tab:blue')

# Add some descriptive titles
plt.title('{} Sounding'.format(station), loc='left')
plt.title('Valid Time: {}'.format(dt), loc='right')

plt.show()
Ejemplo n.º 13
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()
Ejemplo n.º 14
0
def cape(filelist,storm,track):
    #Sort filelist.
    filelist=np.sort(filelist)

    # Get sampling periods (this will be a dictionary). See the toolbox
    print('Retrieving sampling periods')
    sampleperiods=getsamplingperiods(filelist,3.)

    # Iterate over all sampling periods.
    for sampindex,periodskey in enumerate(sampleperiods):

        #Allocate starting (stdt) and ending date (endt). Remeber dt is the convetional short-name for date.
        stdt=periodskey
        endt=sampleperiods[periodskey]

        # Define sampling period string
        period=str(stdt.hour)+'_'+str(stdt.day)+'-'+str(endt.hour)+'_'+str(endt.day)

        # Create new-empty lists.
        lats=[]
        lons=[]
        xs=[]
        ys=[]
        capes=[]
        cins=[]

        print('start filelist loop')
        # Iterate over all files.
        for filename in filelist:



            # Select end-name of file by inspecting filename string. Notice how filename can change how file is read.
            if 'radazm' in filename.split('/')[-1] or 'eol' in filename.split('/')[-1]:
                end='radazm'
            else:
                end='avp'
            # Obtain properties of file, i.e., launch time and location into a dictionary (dicc).
            dicc=findproperties(filename,end)

            # Condition to see if current file is in sampling period.
            # Notice how if structure is constructed, condition finds times outside of sampling period and
            # if found outside the sampling period, continue to next file.
            if dicc['Launch Time']<stdt or dicc['Launch Time'] > endt:
                continue

            nump=np.genfromtxt(filename,skip_header=16,skip_footer=0)
            temperature=clean1(nump[:,5])
            pressure=clean1(nump[:,4])
            Height=clean1(nump[:,13])
            if np.nanmax(Height)<3500:
                continue
            #Clean for cape
            RelH=clean1(nump[:,7])
            lon=clean1(nump[:,14])
            lat=clean1(nump[:,15])
            lon=clean1(lon)
            lat=clean1(lat)
            mlon=np.nanmean(lon)
            mlat=np.nanmean(lat)
            RH=RelH/100
            T,P,rh,dz=cleanforcape(temperature,pressure,RH,Height)

            #Metpy set-up
            T=np.flip(T,0)
            rh=np.flip(rh,0)
            p=np.flip(P,0)
            dz=np.flip(dz,0)
            p=p*units.hPa
            T=T*units.celsius


            mixing=rh*mpcalc.saturation_mixing_ratio(p,T)
            epsilon=0.6219800858985514
            Tv=mpcalc.virtual_temperature(T, mixing,
                                      molecular_weight_ratio=epsilon)
            dwpoint=mpcalc.dewpoint_rh(T, rh)

            blh_indx=np.where(dz<500)
            try:
                parcelprofile=mpcalc.parcel_profile(p,np.nanmean(T[blh_indx])*units.celsius,mpcalc.dewpoint_rh(np.nanmean(T[blh_indx])*units.celsius, np.nanmean(rh[blh_indx]))).to('degC')
                Tv_parcelprofile=mpcalc.virtual_temperature(parcelprofile, mixing,
                                          molecular_weight_ratio=epsilon)
                cape,cin=cape_cin(p,Tv,dwpoint,Tv_parcelprofile,dz,T)
            except:
                continue

            plotskewT=True
            if plotskewT==True:

                os.system('mkdir figs/skewt')
                fig = plt.figure(figsize=(9, 9))
                skew = SkewT(fig, rotation=45)
                skew.ax.set_ylim(1000, 100)
                skew.ax.set_xlim(-40, 60)

                skew.plot(p, dwpoint, 'g',label=r'$T_{dp}$')
                skew.plot(p, Tv, 'r',label=r'$T_v$')
                plt.text(-120,120,str(np.around(cape,2)),fontsize=14,fontweight='bold')

                # 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,Tv_parcelprofile,'k',label=r'$T_{v env}$')
                skew.shade_cin(p, T, parcelprofile,label='CIN')
                skew.shade_cape(p, Tv, Tv_parcelprofile,label='CAPE')
                skew.plot_dry_adiabats()
                skew.plot_moist_adiabats()

                plt.legend()
                plt.title(storm + ' on' + period,fontsize=14)
                plt.savefig('figs/skewt/'+storm+str(dicc['Launch Time'].time())+'.png')
                #plt.show()
                plt.close()

            r,theta=cart_to_cylindr(mlon,mlat,track,dicc['Launch Time'])
            if not(np.isnan(r)) and not(np.isnan(theta)) and not(np.isnan(cape.magnitude)):
                xs.append(r*np.cos(theta))
                ys.append(r*np.sin(theta))
                capes.append(cape.magnitude)
                cins.append(cin)

            fig = plt.figure(figsize=(13, 9))
            plt.scatter(xs,ys,c=np.asarray(capes),cmap='jet')
            for i,xi in enumerate(xs):
                plt.text(xi,ys[i]+10,str(np.around(capes[i],1)))

        plt.colorbar(label=r"$J/kg$')
        plt.scatter(0,0,marker='v',s=100,color='black')
        plt.grid()
        plt.xlabel('X distance [km]')
        plt.ylabel('Y distance [km]')
        plt.title('CAPE distribution for '+storm+' on '+period,fontsize=14)
        plt.savefig('figs/cape'+storm+period+'.png')