#!/usr/bin/env python

"""
some code to do a stick plot with MPL

This version uses matplotlib's quiver.

"""

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

import datetime


def stick(axes, times, speeds, directions, units=''):
    """
    Create a stick plot of the given data on the given axes.
   
    Stick plots are commonlyu used to display time series of
    a vector quantity at a point, such as wind or ocean current observations.
    
    Call signature::
        stick(axes, times, speed, direction, units='m/s')
   
    Arguments: 
       *axes*:  The axes object you want to plot on
       *times*: An array of datetime objects giving the time of the
                observations
       *speeds*: An array of the velocities of the observations
       *directions*: An array of the directions of the observations (in
                     degrees from North, where North is up on the plot)
       *units*:  A string with the units of the observation
    
    """

    props = {'units' : "inches",
             'width' : 0.02,
             'headwidth': 0,
             'headlength': 0,
             'headaxislength': 0,
             #'scale' : .1,
             }

    label_scale = np.floor(speeds.max() / 10) * 10
    if label_scale == 0:
        label_scale = 5.0
    unit_label = "%3g %s"%(label_scale, units)

    times = mpl.dates.date2num(times)
    y = np.zeros_like(speeds)
    dir_rad = directions / 180. * np.pi
    u = np.sin(dir_rad) * speeds
    v = np.cos(dir_rad) * speeds

    Q = axes.quiver(times, y, u, v, **props)
    axes.quiverkey(Q, X=0.1, Y=0.95, U=label_scale, label=unit_label, coordinates='axes', labelpos='S')
    axes.yaxis.set_major_locator(mpl.ticker.NullLocator())
    
    locator = mpl.dates.AutoDateLocator()
    axes.xaxis.set_major_locator(locator)
    axes.xaxis.set_major_formatter(mpl.dates.AutoDateFormatter(locator))


def vector(axes, times, speeds, directions, units=''):
    """
    Create a "vector" plot of the given data on the given axes.
   
    A vector plot is a way to plot a time series of a vector quantity at a
    point, such as wind or ocean current observations. For antoher option,
    see "stick"
    
    Call signature::
        stick(axes, times, speed, direction, units='m/s')
   
    Arguments: 
       *axes*:  The axes object you want to plot on
       *times*: An array of datetime objects giving the time of the
                observations
       *speeds*: An array of the velocities of the observations
       *directions*: An array of the directions of the observations (in
                     degrees from North, where North is up on the plot)
       *units*:  A string with the units of the observation
    
    """

    props = {'units' : "dots",
             'width' : 2,
             'headwidth': 3,
             'headlength': 6,
             'headaxislength': 6,
             'scale' : .05,
             }

    times = mpl.dates.date2num(times)
    dir_rad = directions / 180. * np.pi
    u = np.sin(dir_rad)
    v = np.cos(dir_rad)

    Q = axes.quiver(times, speeds, u, v, **props)
    axes.plot(times, speeds, 'o')


    xaxis = axes.xaxis

    xaxis.set_major_locator(mpl.dates.DayLocator())
    Fmt = mpl.dates.DateFormatter('%m/%d')
    xaxis.set_major_formatter(Fmt)

    axes.set_ylabel(units, rotation='horizontal')
    axes.set_ylim(ymin=0)
    axes.grid('on')
    

    locator = mpl.dates.AutoDateLocator()
    axes.xaxis.set_major_locator(locator)
    axes.xaxis.set_major_formatter(mpl.dates.AutoDateFormatter(locator, tz=None))

if __name__ == '__main__':

    ## some sample data:

#    data = np.array([(10,  0.5),
#                     (10,  22.5),
#                     (10, 45.0),
#                     (10, 67.5),
#                     (10, 90.0),
#                     (10, 112.5),
#                     (10, 135.0),
#                     (10, 157.5),
#                     (10, 180.0),
#                     (10, 202.5),
#                     (10, 225.0),
#                     (10, 247.5),
#                     (10, 270.0),
#                     (10, 292.5),
#                     (10, 315.0),
#                     (10, 337.5),
#                     ( 8, 157.5),
#                     (12, 180.0),
#                     (15, 202.5),
#                     ( 7, 225.0),
#                     ( 5, 247.5),
#                     (16, 270.0),
#                     (20, 292.5),
#                     (22, 315.0),
#                     (15, 337.5),
#                     (12,  22.5),
#                     (17, 25.0),
#                     (18, 30),
#                     ], dtype=np.float)
#    speeds  = data[:,0]
#    directions  = data[:,1]

    data = np.array([[ 220.,    3.],
                     [ 200.,    2.],
                     [ 230.,    3.],
                     [ 220.,    1.],
                     [ 240.,    2.],
                     [ 240.,    2.],
                     [ 240.,    3.],
                     [ 270.,    3.],
                     [ 270.,    4.],
                     [ 270.,    5.],
                     [ 270.,    4.],
                     [ 290.,    2.],
                     [ 320.,    3.],
                     [ 300.,    5.],
                     [ 280.,    6.],
                     [ 260.,    5.],
                     [ 260.,    5.],
                     [ 270.,    5.],
                     [ 260.,    5.],
                     [ 250.,    5.],
                     [ 240.,    4.],
                     [ 260.,    5.],
                     [ 250.,    4.],
                     [ 250.,    5.],
                     [ 240.,    4.],
                     [ 230.,    4.],
                     [ 270.,    5.],
                     [ 250.,    2.],
                     [ 260.,    3.],
                     [ 240.,    3.],
                     [ 270.,    4.],
                     [ 270.,    5.],
                     [ 270.,    4.],
                     [ 280.,    3.],
                     [ 290.,    3.],
                     [ 290.,    3.],
                     [ 310.,    5.],
                     [ 290.,    7.],
                     [ 290.,    8.],
                     [ 280.,    7.],
                     [ 280.,    7.],
                     [ 270.,    7.],
                     [ 280.,    7.],
                     [ 280.,    6.],
                     [ 280.,    4.],
                     [ 300.,    5.],
                     [ 290.,    5.],
                     [ 290.,    3.],
                     [ 300.,    4.],
                     [ 290.,    4.],
                     [ 300.,    4.],
                     [ 280.,    4.],
                     [ 290.,    4.],
                     [ 290.,    4.],
                     [ 280.,    5.],
                     [ 270.,    4.],
                     [ 250.,    4.],
                     [ 250.,    2.],
                     [ 270.,    3.],
                     [ 280.,    3.],
                     [ 290.,    5.],
                     [ 290.,    6.],
                     [ 290.,    6.],
                     [ 290.,    6.],
                     [ 300.,    6.],
                     [ 290.,    5.],
                     [ 290.,    5.],
                     [ 300.,    5.],
                     [ 300.,    5.],
                     [ 300.,    5.],
                     [ 300.,    4.],
                     [ 300.,    4.],
                     [ 310.,    3.],
                     [ 290.,    2.],
                     [ 270.,    2.],
                     [ 270.,    1.],
                     [ 300.,    1.],
                     [ 290.,    2.],
                     [ 320.,    2.],
                     [ 310.,    2.],
                     [ 310.,    3.],
                     [ 280.,    3.],
                     [ 280.,    3.],
                     [ 280.,    1.],
                     [ 310.,    3.],
                     [ 320.,    3.],
                     [ 290.,    5.],
                     [ 300.,    5.],
                     [ 290.,    6.],
                     [ 290.,    5.],
                     [ 290.,    6.],
                     [ 290.,    4.],
                     [ 280.,    5.],
                     [ 290.,    4.],
                     [ 300.,    3.],
                     [ 300.,    5.],
                     [ 290.,    4.],
                     [ 270.,    1.],
                     [ 310.,    2.],
                     [ 340.,    1.],
                     [ 310.,    3.],
                     [ 290.,    2.],
                     [ 290.,    1.],
                     [ 290.,    2.],
                     [ 270.,    2.],
                     [ 260.,    3.],
                     [ 270.,    1.],
                     [ 260.,    1.],
                     [ 270.,    1.],
                     [ 280.,    3.],
                     [ 290.,    4.],
                     [ 290.,    4.],
                     [ 290.,    5.],
                     [ 280.,    4.],
                     [ 290.,    4.],
                     [ 270.,    4.],
                     [ 260.,    4.],
                     [ 250.,    4.],
                     [ 240.,    2.],
                     [ 210.,    2.],
                     ])

    speeds  = data[:,1]
    directions  = data[:,0]
    times = range(len(speeds))
    times = [datetime.datetime(2009, 5, 13, 0) + datetime.timedelta(hours=h*48) for h in times]
    
    fig = plt.figure(1)
    fig.clear()

    ax = fig.add_subplot(2,1,1)
    stick(ax, times, speeds, directions, units='m/s')

    ax = fig.add_subplot(2,1,2)
    vector(ax, times, speeds, directions, units='$m/s$')

    fig.autofmt_xdate(bottom=0.18)

    plt.draw()
    plt.show()

