def displayTimeseriesPlot(nc,dataVar,data,timeVal,title):
    """ Takes NetCDF dataset, the variable data object, the data values, the 
    time values and the title of the plot. Plots time series of the data values """
    
    import datetime as dt
    import matplotlib.pyplot as plt
    import matplotlib.dates as mdates
    import netcdfUtils
    
    dayLocator    = mdates.DayLocator()
    hourLocator   = mdates.HourLocator()
    dateFmt = mdates.DateFormatter('%Y-%m-%d')
    # get the datum and delta from reading time units of the file
    timeVar=netcdfUtils.findTimeVar(nc,dataVar)
    year=timeVar.units[14:18]
    month=timeVar.units[19:21]
    day=timeVar.units[22:24]
    datum = dt.datetime(int(year), int(month),int(day))
    delta = dt.timedelta(seconds=1)
    # Convert the time values to datetime objects
    times = []
    for t in timeVal:
        times.append(datum + int(t) * delta)
   # Plot SST against the datetime objects
    plt.plot(times,data)
    plt.title("Sea surface temperature Timeseries")
    plt.ylabel("SST (" + dataVar.units + ")")
    plt.xlabel("Time")
    # format the ticks
    ax = plt.gca()
    ax.xaxis.set_major_locator(dayLocator)
    ax.xaxis.set_major_formatter(dateFmt)
    ax.xaxis.set_minor_locator(hourLocator)
    plt.show()
def extractMapData(nc, dataVar, tIndex, zIndex):
    """ TODO: add a docstring! """
    # Find the number of dimensions for the data variable
    numDims = len(dataVar.dimensions)
    if numDims < 2 or numDims > 4:
        raise ValueError("Cannot extract data from variable with %d dimensions" % numDims)
    
    # Check that longitude and latitude variables are present
    lonVar = netcdfUtils.findLongitudeVar(nc, dataVar)
    latVar = netcdfUtils.findLatitudeVar(nc, dataVar)
    if lonVar is None or latVar is None:
        raise ValueError("Cannot extract map data if longitude and latitude are not present")
    
    # If this is a four-dimensional variable, assume that there are t,z,y,x axes, in this order
    if numDims == 4:
        return dataVar[tIndex,zIndex]
    elif numDims == 3:
        # We don't know if the first dimension is t or z
        tVar = netcdfUtils.findTimeVar(nc, dataVar)
        if tVar is None:
            # We assume the first dimension is z
            return dataVar[zIndex]
        else:
            # We assume the first dimension is t
            return dataVar[tIndex]
    else:
        # numDims must be 2
        return dataVar[:]
def plotTimeseries(filename,varIdentifier,lonVal,latVal,zVal):
    """Takes five aruguments i.e. a string representing location of NetCDF file,
    variable identifier, the longitude and latitude values in degress as well as
    the value of the vertical axis in the units used in the data file
    (this is ignored if the data variable has no vertical dimension). Uses
    the extractTimeseries() function in the extract module and plot using the 
    displayTimeseriesPlot() function in the plotting module."""
    import netcdfUtils
    import netCDF4 
    import plotting
    #A netCDF4 dataset Object
    nc=netCDF4.Dataset(filename) 
    # A varible object representing a data variable (e.g. sst)
    dataVar=nc.variables[varIdentifier] 
    # Check that longitude,latitude, vertical and time variables are present
    lonVar = netcdfUtils.findLongitudeVar(nc, dataVar)
    latVar = netcdfUtils.findLatitudeVar(nc, dataVar)
    timeVar=netcdfUtils.findTimeVar(nc,dataVar)
    
    #check if the file has latitude, longitude and time dimensions
    if lonVar is None or latVar is None or timeVar is None:
        raise ValueError("Cannot extract map data if longitude, latitude & time are abscent")
   
    #extract data as well as the vertical and longitude/latitude coordinates      
    data=extract.extractTimeseries(nc,dataVar,lonVal,latVal,zVal) 
    # get the title of the plot
    title=netcdfUtils.getTitle(dataVar)
    #plot the data against time
    plotting.displayTimeseriesPlot(nc,dataVar,data[0],data[1],title)
       
    return
#### Here are some test functions.
#### Simply run this script to run them.

#if __name__ == '__main__':
    #plotMap("POLCOMS.nc", "POT", 0,0)
     #plotMap("C:/Users/Developer202/Desktop/MWR/Data/Reanalysis/Surface/vwnd.mon.mean.nc","vwnd",800,0)
     #plotMap("C:/Users/Developer202/Desktop/MWR/Data/Reanalysis/Surface/uwnd.mon.mean.nc","uwnd",800,0)
    #plotMap("GlobModel_temp.nc", "ta", 0,5)
    #plotMap("GlobModel_ozone.nc", "colo3", 0,5)
    #plotMap("rfe2015_02_seas_anom.nc","rfe",0,5)
    #plotMap("sst.day.mean.2014.v2.nc","sst",0,5)
    #plotMap("FOAM_Natl.nc", "ssh", 0,0)
    #plotMap("HadCEM.nc", "salinity", 0,10)
    # The OSTIA dataset is large, so this test can be slow.  Uncomment
    # this line to run it
    #plotMap("OSTIA.nc", "analysed_sst", 0,0)
    
def extractTimeseries(nc,dataVar,lonVal,latVal,zVal):
    """ Takes five arguments; the NetCDF dataset, the variable object, the 
    longitude value, the latitude value and the vertical value and use them to 
    extracts data and time values at the point described. It returns the data of 
    the  and variable represented by the variable object the time values for 
    each point described by the longitude, latitude and vertical values in the
    NetCDF file"""
    # Find the number of dimensions for the data variable
    numDims = len(dataVar.dimensions)
    
    # Check if the number of dimensions and raise error if they are not 3 or 4  
    if numDims < 3 or numDims > 4:
        raise ValueError("Cannot extract data from variable with %d dimensions" % numDims)
    # Check if longitude, latitude and vertical dimensions are present
    lonVar = netcdfUtils.findLongitudeVar(nc, dataVar)
    latVar = netcdfUtils.findLatitudeVar(nc, dataVar)
    timeVar=netcdfUtils.findTimeVar(nc,dataVar)
    zVar=netcdfUtils.findVerticalVar(nc,dataVar)
    timeVal=timeVar[:]
    # check if the longitude, latitude or the time dimension is abscent and raise error
    if lonVar is None or latVar is None or timeVar is None:
        raise ValueError("Cannot extract map data if longitude, latitude and time dimensios are abscent")
    
   # map the longitutude value from range (-180 to 180) onto (0 to 360) in the data file
    #lonVal=lonVal+180 
    if min(lonVar[:])>=0:
        if lonVal<0:
            lonVal=lonVal+180
    # if the dimensions are 4 i.e. time,vertical,latitude and longitude 
    if numDims == 4:
         #get the vertical,longitude and latitude indices
        lonIndex=utils.findNearestIndex(lonVar,lonVal)
        latIndex=utils.findNearestIndex(latVar,latVal)
        zIndex=utils.findNearestIndex(zVar,zVal)
        return dataVar[:,zIndex,latIndex,lonIndex],timeVal
    # if the dimensions are 3 ie time, latitude and longitude
    elif numDims == 3: 
        #get the longitude and latitude indices
        lonIndex=utils.findNearestIndex(lonVar,lonVal)
        latIndex=utils.findNearestIndex(latVar,latVal)         
        return dataVar[:,latIndex,lonIndex],timeVal