Wind Speed and Gust from NDBC SOS service

Get CSV data from NDBC SOS service using OWSlib, then read CSV data and plot using Pandas


In [1]:
%matplotlib inline

In [2]:
from datetime import datetime
import cStringIO
import pandas as pd
from owslib.sos import SensorObservationService

In [3]:
# pick a buoy, any buoy
#sta_id='44066'  # texas tower
sta_id='44013'  # boston buoy

In [4]:
# pick a start & stop time
start = '2013-06-12T00:00:00Z'
stop = '2013-06-14T00:00:00Z'

In [5]:
from IPython.core.display import HTML
HTML('<iframe src=http://www.ndbc.noaa.gov/station_page.php?station=%s width=950 height=400></iframe>' % sta_id)


Out[5]:

In [6]:
ndbc=SensorObservationService('http://sdf.ndbc.noaa.gov/sos/server.php?request=GetCapabilities&service=SOS')

In [7]:
id=ndbc.identification
id.title


Out[7]:
'National Data Buoy Center SOS'

In [8]:
contents = ndbc.contents
network = contents['network-all']
network.description


Out[8]:
'All stations on the NDBC SOS server'

In [9]:
id.title


Out[9]:
'National Data Buoy Center SOS'

In [10]:
rfs = network.response_formats

In [11]:
print '\n'.join(rfs)


text/xml;subtype="om/1.0.0"
text/csv
text/tab-separated-values
application/vnd.google-earth.kml+xml
text/xml;schema="ioos/0.6.1"
application/ioos+xml;version=0.6.1

In [12]:
station = contents['station-%s' % sta_id]

In [13]:
station.name


Out[13]:
'urn:ioos:station:wmo:44013'

In [14]:
station.description


Out[14]:
'BOSTON 16 NM East of Boston, MA'

In [15]:
getob = ndbc.get_operation_by_name('getobservation')

In [16]:
getob.parameters


Out[16]:
{'observedProperty': {'values': ['air_temperature',
   'air_pressure_at_sea_level',
   'sea_water_electrical_conductivity',
   'currents',
   'sea_water_salinity',
   'sea_floor_depth_below_sea_surface',
   'sea_water_temperature',
   'waves',
   'winds']},
 'responseFormat': {'values': ['text/xml;subtype="om/1.0.0"',
   'text/csv',
   'text/tab-separated-values',
   'application/vnd.google-earth.kml+xml',
   'text/xml;schema="ioos/0.6.1"',
   'application/ioos+xml;version=0.6.1']}}

In [17]:
# issue the SOS get_obs request
response = ndbc.get_observation(offerings=['urn:ioos:station:wmo:%s' % sta_id],
                                 responseFormat='text/csv',
                                 observedProperties=['winds'],
                                 eventTime='%s/%s' % (start,stop))

In [18]:
response


Out[18]:
'station_id,sensor_id,"latitude (degree)","longitude (degree)",date_time,"depth (m)","wind_from_direction (degree)","wind_speed (m/s)","wind_speed_of_gust (m/s)","upward_air_velocity (m/s)"\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T00:50:00Z,-5.00,20.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T01:50:00Z,-5.00,30.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T02:50:00Z,-5.00,10.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T03:50:00Z,-5.00,250.0,2.00,2.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T04:50:00Z,-5.00,230.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T05:50:00Z,-5.00,240.0,2.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T06:50:00Z,-5.00,250.0,2.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T07:50:00Z,-5.00,270.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T08:50:00Z,-5.00,300.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T09:50:00Z,-5.00,300.0,5.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T10:50:00Z,-5.00,280.0,5.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T11:50:00Z,-5.00,270.0,5.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T12:50:00Z,-5.00,270.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T13:50:00Z,-5.00,300.0,8.00,9.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T14:50:00Z,-5.00,300.0,7.00,8.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T15:50:00Z,-5.00,300.0,6.00,7.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T16:50:00Z,-5.00,300.0,7.00,8.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T17:50:00Z,-5.00,310.0,8.00,9.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T18:50:00Z,-5.00,360.0,6.00,8.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T19:50:00Z,-5.00,340.0,3.00,4.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T20:50:00Z,-5.00,340.0,7.00,8.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T21:50:00Z,-5.00,330.0,6.00,7.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T22:50:00Z,-5.00,350.0,5.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-12T23:50:00Z,-5.00,330.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T00:50:00Z,-5.00,350.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T01:50:00Z,-5.00,320.0,4.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T02:50:00Z,-5.00,330.0,5.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T03:50:00Z,-5.00,300.0,4.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T04:50:00Z,-5.00,300.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T05:50:00Z,-5.00,280.0,5.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T06:50:00Z,-5.00,290.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T07:50:00Z,-5.00,300.0,4.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T08:50:00Z,-5.00,300.0,4.00,5.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T09:50:00Z,-5.00,270.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T10:50:00Z,-5.00,260.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T11:50:00Z,-5.00,260.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T12:50:00Z,-5.00,230.0,2.00,2.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T13:50:00Z,-5.00,80.0,2.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T14:50:00Z,-5.00,110.0,2.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T15:50:00Z,-5.00,160.0,3.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T16:50:00Z,-5.00,160.0,4.00,4.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T17:50:00Z,-5.00,160.0,2.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T18:50:00Z,-5.00,140.0,5.00,6.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T19:50:00Z,-5.00,180.0,5.00,7.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T20:50:00Z,-5.00,160.0,3.00,4.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T21:50:00Z,-5.00,130.0,2.00,3.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T22:50:00Z,-5.00,110.0,3.00,4.00,\nurn:ioos:station:wmo:44013,urn:ioos:sensor:wmo:44013::anemometer1,42.35,-70.69,2013-06-13T23:50:00Z,-5.00,50.0,4.00,5.00,\n'

In [19]:
df2 = pd.read_csv(cStringIO.StringIO(response.strip()),index_col='date_time',parse_dates=True)  # skip the units row

In [20]:
df2.head()


Out[20]:
station_id sensor_id latitude (degree) longitude (degree) depth (m) wind_from_direction (degree) wind_speed (m/s) wind_speed_of_gust (m/s) upward_air_velocity (m/s)
date_time
2013-06-12 00:50:00 urn:ioos:station:wmo:44013 urn:ioos:sensor:wmo:44013::anemometer1 42.35 -70.69 -5.0 20.0 5.0 6.0 NaN
2013-06-12 01:50:00 urn:ioos:station:wmo:44013 urn:ioos:sensor:wmo:44013::anemometer1 42.35 -70.69 -5.0 30.0 3.0 3.0 NaN
2013-06-12 02:50:00 urn:ioos:station:wmo:44013 urn:ioos:sensor:wmo:44013::anemometer1 42.35 -70.69 -5.0 10.0 3.0 3.0 NaN
2013-06-12 03:50:00 urn:ioos:station:wmo:44013 urn:ioos:sensor:wmo:44013::anemometer1 42.35 -70.69 -5.0 250.0 2.0 2.0 NaN
2013-06-12 04:50:00 urn:ioos:station:wmo:44013 urn:ioos:sensor:wmo:44013::anemometer1 42.35 -70.69 -5.0 230.0 3.0 3.0 NaN

In [21]:
df2[['wind_speed_of_gust (m/s)','wind_speed (m/s)']].plot(figsize=(12,4),title=station.description,legend=True)


Out[21]:
<matplotlib.axes._subplots.AxesSubplot at 0x7effdbdf3590>

In [ ]: