from siphon.catalog import TDSCatalog
best_gfs = TDSCatalog('http://thredds.ucar.edu/thredds/catalog/grib/NCEP/GFS/Global_0p5deg/catalog.xml?dataset=grib/NCEP/GFS/Global_0p5deg/Best')
best_gfs.datasets

"""
Explanation: Using Siphon to query the NetCDF Subset Service
First we construct a TDSCatalog instance pointing to our dataset of interest, in
this case TDS' "Best" virtual dataset for the GFS global 0.5 degree collection of
GRIB files. We see this catalog contains a single dataset.
End of explanation
"""


best_ds = list(best_gfs.datasets.values())[0]
best_ds.access_urls

"""
Explanation: We pull out this dataset and look at the access urls.
End of explanation
"""


from siphon.ncss import NCSS
ncss = NCSS(best_ds.access_urls['NetcdfSubset'])

"""
Explanation: Note the NetcdfSubset entry, which we will use with our NCSS class.
End of explanation
"""


query = ncss.query()

"""
Explanation: We can then use the ncss object to create a new query object, which
facilitates asking for data from the server.
End of explanation
"""


from datetime import datetime
query.lonlat_point(-105, 40).time(datetime.utcnow())
query.accept('netcdf4')
query.variables('Temperature_isobaric', 'Relative_humidity_isobaric')

"""
Explanation: We construct a query asking for data corresponding to latitude 40N and longitude 105W, for the current time.
We also ask for NetCDF version 4 data, for the variables 'Temperature_isobaric' and 'Relative_humidity_isobaric'. This request will return all vertical levels for a single point and single time. Note the string representation of the query is a properly encoded query string.
End of explanation
"""


data = ncss.get_data(query)
list(data.variables.keys())

"""
Explanation: We now request data from the server using this query. The NCSS class handles parsing this NetCDF data (using the netCDF4 module). If we print out the variable names, we see our requested variables, as well as a few others (more metadata information)
End of explanation
"""


temp = data.variables['Temperature_isobaric']
relh = data.variables['Relative_humidity_isobaric']
press = data.variables['isobaric3']
press_vals = press[:].squeeze()

"""
Explanation: We'll pull out the variables we want to use, as well as the pressure values (from the isobaric3 variable).
End of explanation
"""


import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1, figsize=(9, 8))
ax.plot(temp[:].squeeze(), press_vals, 'r', linewidth=2)
ax.set_xlabel(temp.standard_name + ' (%s)' % temp.units)
ax.set_ylabel(press.standard_name + ' (%s)' % press.units)

# Create second plot with shared y-axis
ax2 = plt.twiny(ax)
ax2.plot(relh[:].squeeze(), press_vals, 'g', linewidth=2)
ax2.set_xlabel(relh.standard_name + ' (%s)' % relh.units)
ax.set_ylim(press_vals.max(), press_vals.min())
ax.grid(True)

"""
Explanation: Now we can plot these up using matplotlib.
End of explanation
"""


