Commits

James Morrison committed 66ccd54

first commit

Comments (0)

Files changed (3)

+
+CeCILL-B FREE SOFTWARE LICENSE AGREEMENT
+
+
+    Notice
+
+This Agreement is a Free Software license agreement that is the result
+of discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:
+
+    * firstly, compliance with the principles governing the distribution
+      of Free Software: access to source code, broad rights granted to
+      users,
+    * secondly, the election of a governing law, French law, with which
+      it is conformant, both as regards the law of torts and
+      intellectual property law, and the protection that it offers to
+      both authors and holders of the economic rights over software.
+
+The authors of the CeCILL-B (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
+license are: 
+
+Commissariat ŕ l'Energie Atomique - CEA, a public scientific, technical
+and industrial research establishment, having its principal place of
+business at 25 rue Leblanc, immeuble Le Ponant D, 75015 Paris, France.
+
+Centre National de la Recherche Scientifique - CNRS, a public scientific
+and technological establishment, having its principal place of business
+at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
+
+Institut National de Recherche en Informatique et en Automatique -
+INRIA, a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.
+
+
+    Preamble
+
+This Agreement is an open source software license intended to give users
+significant freedom to modify and redistribute the software licensed
+hereunder.
+
+The exercising of this freedom is conditional upon a strong obligation
+of giving credits for everybody that distributes a software
+incorporating a software ruled by the current license so as all
+contributions to be properly identified and acknowledged.
+
+In consideration of access to the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the software's author, the holder of the
+economic rights, and the successive licensors only have limited liability.
+
+In this respect, the risks associated with loading, using, modifying
+and/or developing or reproducing the software by the user are brought to
+the user's attention, given its Free Software status, which may make it
+complicated to use, with the result that its use is reserved for
+developers and experienced professionals having in-depth computer
+knowledge. Users are therefore encouraged to load and test the
+suitability of the software as regards their requirements in conditions
+enabling the security of their systems and/or data to be ensured and,
+more generally, to use and operate it in the same conditions of
+security. This Agreement may be freely reproduced and published,
+provided it is not altered, and that no provisions are either added or
+removed herefrom.
+
+This Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use thereof to its provisions.
+
+
+    Article 1 - DEFINITIONS
+
+For the purpose of this Agreement, when the following expressions
+commence with a capital letter, they shall have the following meaning:
+
+Agreement: means this license agreement, and its possible subsequent
+versions and annexes.
+
+Software: means the software in its Object Code and/or Source Code form
+and, where applicable, its documentation, "as is" when the Licensee
+accepts the Agreement.
+
+Initial Software: means the Software in its Source Code and possibly its
+Object Code form and, where applicable, its documentation, "as is" when
+it is first distributed under the terms and conditions of the Agreement.
+
+Modified Software: means the Software modified by at least one
+Contribution.
+
+Source Code: means all the Software's instructions and program lines to
+which access is required so as to modify the Software.
+
+Object Code: means the binary files originating from the compilation of
+the Source Code.
+
+Holder: means the holder(s) of the economic rights over the Initial
+Software.
+
+Licensee: means the Software user(s) having accepted the Agreement.
+
+Contributor: means a Licensee having made at least one Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Contribution: means any or all modifications, corrections, translations,
+adaptations and/or new functions integrated into the Software by any or
+all Contributors, as well as any or all Internal Modules.
+
+Module: means a set of sources files including their documentation that
+enables supplementary functions or services in addition to those offered
+by the Software.
+
+External Module: means any or all Modules, not derived from the
+Software, so that this Module and the Software run in separate address
+spaces, with one calling the other when they are run.
+
+Internal Module: means any or all Module, connected to the Software so
+that they both execute in the same address space.
+
+Parties: mean both the Licensee and the Licensor.
+
+These expressions may be used both in singular and plural form.
+
+
+    Article 2 - PURPOSE
+
+The purpose of the Agreement is the grant by the Licensor to the
+Licensee of a non-exclusive, transferable and worldwide license for the
+Software as set forth in Article 5 hereinafter for the whole term of the
+protection granted by the rights over said Software.
+
+
+    Article 3 - ACCEPTANCE
+
+3.1 The Licensee shall be deemed as having accepted the terms and
+conditions of this Agreement upon the occurrence of the first of the
+following events:
+
+    * (i) loading the Software by any or all means, notably, by
+      downloading from a remote server, or by loading from a physical
+      medium;
+    * (ii) the first time the Licensee exercises any of the rights
+      granted hereunder.
+
+3.2 One copy of the Agreement, containing a notice relating to the
+characteristics of the Software, to the limited warranty, and to the
+fact that its use is restricted to experienced users has been provided
+to the Licensee prior to its acceptance as set forth in Article 3.1
+hereinabove, and the Licensee hereby acknowledges that it has read and
+understood it.
+
+
+    Article 4 - EFFECTIVE DATE AND TERM
+
+
+      4.1 EFFECTIVE DATE
+
+The Agreement shall become effective on the date when it is accepted by
+the Licensee as set forth in Article 3.1.
+
+
+      4.2 TERM
+
+The Agreement shall remain in force for the entire legal term of
+protection of the economic rights over the Software.
+
+
+    Article 5 - SCOPE OF RIGHTS GRANTED
+
+The Licensor hereby grants to the Licensee, who accepts, the following
+rights over the Software for any or all use, and for the term of the
+Agreement, on the basis of the terms and conditions set forth hereinafter.
+
+Besides, if the Licensor owns or comes to own one or more patents
+protecting all or part of the functions of the Software or of its
+components, the Licensor undertakes not to enforce the rights granted by
+these patents against successive Licensees using, exploiting or
+modifying the Software. If these patents are transferred, the Licensor
+undertakes to have the transferees subscribe to the obligations set
+forth in this paragraph.
+
+
+      5.1 RIGHT OF USE
+
+The Licensee is authorized to use the Software, without any limitation
+as to its fields of application, with it being hereinafter specified
+that this comprises:
+
+   1. permanent or temporary reproduction of all or part of the Software
+      by any or all means and in any or all form.
+
+   2. loading, displaying, running, or storing the Software on any or
+      all medium.
+
+   3. entitlement to observe, study or test its operation so as to
+      determine the ideas and principles behind any or all constituent
+      elements of said Software. This shall apply when the Licensee
+      carries out any or all loading, displaying, running, transmission
+      or storage operation as regards the Software, that it is entitled
+      to carry out hereunder.
+
+
+      5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
+
+The right to make Contributions includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting software.
+
+The Licensee is authorized to make any or all Contributions to the
+Software provided that it includes an explicit notice that it is the
+author of said Contribution and indicates the date of the creation thereof.
+
+
+      5.3 RIGHT OF DISTRIBUTION
+
+In particular, the right of distribution includes the right to publish,
+transmit and communicate the Software to the general public on any or
+all medium, and by any or all means, and the right to market, either in
+consideration of a fee, or free of charge, one or more copies of the
+Software by any means.
+
+The Licensee is further authorized to distribute copies of the modified
+or unmodified Software to third parties according to the terms and
+conditions set forth hereinafter.
+
+
+        5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
+
+The Licensee is authorized to distribute true copies of the Software in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Software is
+redistributed, the Licensee allows effective access to the full Source
+Code of the Software at a minimum during the entire period of its
+distribution of the Software, it being understood that the additional
+cost of acquiring the Source Code shall not exceed the cost of
+transferring the data.
+
+
+        5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
+
+If the Licensee makes any Contribution to the Software, the resulting
+Modified Software may be distributed under a license agreement other
+than this Agreement subject to compliance with the provisions of Article
+5.3.4.
+
+
+        5.3.3 DISTRIBUTION OF EXTERNAL MODULES
+
+When the Licensee has developed an External Module, the terms and
+conditions of this Agreement do not apply to said External Module, that
+may be distributed under a separate license agreement.
+
+
+        5.3.4 CREDITS
+
+Any Licensee who may distribute a Modified Software hereby expressly
+agrees to:
+
+   1. indicate in the related documentation that it is based on the
+      Software licensed hereunder, and reproduce the intellectual
+      property notice for the Software,
+
+   2. ensure that written indications of the Software intended use,
+      intellectual property notice and license hereunder are included in
+      easily accessible format from the Modified Software interface,
+
+   3. mention, on a freely accessible website describing the Modified
+      Software, at least throughout the distribution term thereof, that
+      it is based on the Software licensed hereunder, and reproduce the
+      Software intellectual property notice,
+
+   4. where it is distributed to a third party that may distribute a
+      Modified Software without having to make its source code
+      available, make its best efforts to ensure that said third party
+      agrees to comply with the obligations set forth in this Article .
+
+If the Software, whether or not modified, is distributed with an
+External Module designed for use in connection with the Software, the
+Licensee shall submit said External Module to the foregoing obligations.
+
+
+        5.3.5 COMPATIBILITY WITH THE CeCILL AND CeCILL-C LICENSES
+
+Where a Modified Software contains a Contribution subject to the CeCILL
+license, the provisions set forth in Article 5.3.4 shall be optional.
+
+A Modified Software may be distributed under the CeCILL-C license. In
+such a case the provisions set forth in Article 5.3.4 shall be optional.
+
+
+    Article 6 - INTELLECTUAL PROPERTY
+
+
+      6.1 OVER THE INITIAL SOFTWARE
+
+The Holder owns the economic rights over the Initial Software. Any or
+all use of the Initial Software is subject to compliance with the terms
+and conditions under which the Holder has elected to distribute its work
+and no one shall be entitled to modify the terms and conditions for the
+distribution of said Initial Software.
+
+The Holder undertakes that the Initial Software will remain ruled at
+least by this Agreement, for the duration set forth in Article 4.2.
+
+
+      6.2 OVER THE CONTRIBUTIONS
+
+The Licensee who develops a Contribution is the owner of the
+intellectual property rights over this Contribution as defined by
+applicable law.
+
+
+      6.3 OVER THE EXTERNAL MODULES
+
+The Licensee who develops an External Module is the owner of the
+intellectual property rights over this External Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution.
+
+
+      6.4 JOINT PROVISIONS
+
+The Licensee expressly undertakes:
+
+   1. not to remove, or modify, in any manner, the intellectual property
+      notices attached to the Software;
+
+   2. to reproduce said notices, in an identical manner, in the copies
+      of the Software modified or not.
+
+The Licensee undertakes not to directly or indirectly infringe the
+intellectual property rights of the Holder and/or Contributors on the
+Software and to take, where applicable, vis-ŕ-vis its staff, any and all
+measures required to ensure respect of said intellectual property rights
+of the Holder and/or Contributors.
+
+
+    Article 7 - RELATED SERVICES
+
+7.1 Under no circumstances shall the Agreement oblige the Licensor to
+provide technical assistance or maintenance services for the Software.
+
+However, the Licensor is entitled to offer this type of services. The
+terms and conditions of such technical assistance, and/or such
+maintenance, shall be set forth in a separate instrument. Only the
+Licensor offering said maintenance and/or technical assistance services
+shall incur liability therefor.
+
+7.2 Similarly, any Licensor is entitled to offer to its licensees, under
+its sole responsibility, a warranty, that shall only be binding upon
+itself, for the redistribution of the Software and/or the Modified
+Software, under terms and conditions that it is free to decide. Said
+warranty, and the financial terms and conditions of its application,
+shall be subject of a separate instrument executed between the Licensor
+and the Licensee.
+
+
+    Article 8 - LIABILITY
+
+8.1 Subject to the provisions of Article 8.2, the Licensee shall be
+entitled to claim compensation for any direct loss it may have suffered
+from the Software as a result of a fault on the part of the relevant
+Licensor, subject to providing evidence thereof.
+
+8.2 The Licensor's liability is limited to the commitments made under
+this Agreement and shall not be incurred as a result of in particular:
+(i) loss due the Licensee's total or partial failure to fulfill its
+obligations, (ii) direct or consequential loss that is suffered by the
+Licensee due to the use or performance of the Software, and (iii) more
+generally, any consequential loss. In particular the Parties expressly
+agree that any or all pecuniary or business loss (i.e. loss of data,
+loss of profits, operating loss, loss of customers or orders,
+opportunity cost, any disturbance to business activities) or any or all
+legal proceedings instituted against the Licensee by a third party,
+shall constitute consequential loss and shall not provide entitlement to
+any or all compensation from the Licensor.
+
+
+    Article 9 - WARRANTY
+
+9.1 The Licensee acknowledges that the scientific and technical
+state-of-the-art when the Software was distributed did not enable all
+possible uses to be tested and verified, nor for the presence of
+possible defects to be detected. In this respect, the Licensee's
+attention has been drawn to the risks associated with loading, using,
+modifying and/or developing and reproducing the Software which are
+reserved for experienced users.
+
+The Licensee shall be responsible for verifying, by any or all means,
+the suitability of the product for its requirements, its good working
+order, and for ensuring that it shall not cause damage to either persons
+or properties.
+
+9.2 The Licensor hereby represents, in good faith, that it is entitled
+to grant all the rights over the Software (including in particular the
+rights set forth in Article 5).
+
+9.3 The Licensee acknowledges that the Software is supplied "as is" by
+the Licensor without any other express or tacit warranty, other than
+that provided for in Article 9.2 and, in particular, without any warranty 
+as to its commercial value, its secured, safe, innovative or relevant 
+nature.
+
+Specifically, the Licensor does not warrant that the Software is free
+from any error, that it will operate without interruption, that it will
+be compatible with the Licensee's own equipment and software
+configuration, nor that it will meet the Licensee's requirements.
+
+9.4 The Licensor does not either expressly or tacitly warrant that the
+Software does not infringe any third party intellectual property right
+relating to a patent, software or any other property right. Therefore,
+the Licensor disclaims any and all liability towards the Licensee
+arising out of any or all proceedings for infringement that may be
+instituted in respect of the use, modification and redistribution of the
+Software. Nevertheless, should such proceedings be instituted against
+the Licensee, the Licensor shall provide it with technical and legal
+assistance for its defense. Such technical and legal assistance shall be
+decided on a case-by-case basis between the relevant Licensor and the
+Licensee pursuant to a memorandum of understanding. The Licensor
+disclaims any and all liability as regards the Licensee's use of the
+name of the Software. No warranty is given as regards the existence of
+prior rights over the name of the Software or as regards the existence
+of a trademark.
+
+
+    Article 10 - TERMINATION
+
+10.1 In the event of a breach by the Licensee of its obligations
+hereunder, the Licensor may automatically terminate this Agreement
+thirty (30) days after notice has been sent to the Licensee and has
+remained ineffective.
+
+10.2 A Licensee whose Agreement is terminated shall no longer be
+authorized to use, modify or distribute the Software. However, any
+licenses that it may have granted prior to termination of the Agreement
+shall remain valid subject to their having been granted in compliance
+with the terms and conditions hereof.
+
+
+    Article 11 - MISCELLANEOUS
+
+
+      11.1 EXCUSABLE EVENTS
+
+Neither Party shall be liable for any or all delay, or failure to
+perform the Agreement, that may be attributable to an event of force
+majeure, an act of God or an outside cause, such as defective
+functioning or interruptions of the electricity or telecommunications
+networks, network paralysis following a virus attack, intervention by
+government authorities, natural disasters, water damage, earthquakes,
+fire, explosions, strikes and labor unrest, war, etc.
+
+11.2 Any failure by either Party, on one or more occasions, to invoke
+one or more of the provisions hereof, shall under no circumstances be
+interpreted as being a waiver by the interested Party of its right to
+invoke said provision(s) subsequently.
+
+11.3 The Agreement cancels and replaces any or all previous agreements,
+whether written or oral, between the Parties and having the same
+purpose, and constitutes the entirety of the agreement between said
+Parties concerning said purpose. No supplement or modification to the
+terms and conditions hereof shall be effective as between the Parties
+unless it is made in writing and signed by their duly authorized
+representatives.
+
+11.4 In the event that one or more of the provisions hereof were to
+conflict with a current or future applicable act or legislative text,
+said act or legislative text shall prevail, and the Parties shall make
+the necessary amendments so as to comply with said act or legislative
+text. All other provisions shall remain effective. Similarly, invalidity
+of a provision of the Agreement, for any reason whatsoever, shall not
+cause the Agreement as a whole to be invalid.
+
+
+      11.5 LANGUAGE
+
+The Agreement is drafted in both French and English and both versions
+are deemed authentic.
+
+
+    Article 12 - NEW VERSIONS OF THE AGREEMENT
+
+12.1 Any person is authorized to duplicate and distribute copies of this
+Agreement.
+
+12.2 So as to ensure coherence, the wording of this Agreement is
+protected and may only be modified by the authors of the License, who
+reserve the right to periodically publish updates or new versions of the
+Agreement, each with a separate number. These subsequent versions may
+address new issues encountered by Free Software.
+
+12.3 Any Software distributed under a given version of the Agreement may
+only be subsequently distributed under the same version of the Agreement
+or a subsequent version.
+
+
+    Article 13 - GOVERNING LAW AND JURISDICTION
+
+13.1 The Agreement is governed by French law. The Parties agree to
+endeavor to seek an amicable solution to any disagreements or disputes
+that may arise during the performance of the Agreement.
+
+13.2 Failing an amicable solution within two (2) months as from their
+occurrence, and unless emergency proceedings are necessary, the
+disagreements or disputes shall be referred to the Paris Courts having
+jurisdiction, by the more diligent Party.
+
+
+Version 1.0 dated 2006-09-05.
+from windrose import WindroseAxes
+from matplotlib import pyplot as plt
+import matplotlib.cm as cm
+from numpy.random import random
+from numpy import arange
+import os
+import numpy as np
+
+bin_values = np.array([0,1.5,3,4.5,6,7.5,9])
+spacing = [0,2,4,6,8,10,12,14,16,18,20]
+results_np = np.genfromtxt('example.his', delimiter = ',')
+
+def new_axes():
+    fig = plt.figure(figsize=(8, 8), dpi=80, facecolor='w', edgecolor='w')
+    rect = [0.1, 0.1, 0.8, 0.8]
+    ax = WindroseAxes(fig, rect, axisbg='w')
+    fig.add_axes(ax)
+    return ax, fig
+
+def set_legend(ax):
+    l = ax.legend(axespad=-0.10, title='Hm0 (metres)')
+    l.title = 'Hm0 in metres'
+    plt.setp(l.get_texts(), fontsize=8)
+
+#Create wave speed and direction variables
+sig_wave_height = results_np[:,5]
+wd = results_np[:,2]
+wd = wd.astype(np.float64)
+sig_wave_height = sig_wave_height.astype(np.float64)
+sig_wave_height = sig_wave_height/100.0
+#windrose like a stacked histogram with normed (displayed in percent) results
+ax, fig = new_axes()
+ax.bar(wd, sig_wave_height, normed=True, opening=1, edgecolor='white', bins=bin_values, nsector=32)
+ax.set_title("Waverose - Radial values indicate percentage of occurences")
+ax.set_ybound(lower=0, upper=17)
+ax.yaxis.set_ticks(spacing)
+ax.yaxis.set_ticklabels(spacing)
+set_legend(ax)
+plt.savefig("waverose.png")    
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+__version__ = '1.4'
+__author__ = 'Lionel Roubeyrie'
+__mail__ = 'lionel.roubeyrie@gmail.com'
+__license__ = 'CeCILL-B'
+
+import matplotlib
+import matplotlib.cm as cm
+import numpy as np
+from matplotlib.patches import Rectangle, Polygon
+from matplotlib.ticker import ScalarFormatter, AutoLocator
+from matplotlib.text import Text, FontProperties
+from matplotlib.projections.polar import PolarAxes
+from numpy.lib.twodim_base import histogram2d
+import matplotlib.pyplot as plt
+from pylab import poly_between
+
+RESOLUTION = 100
+ZBASE = -1000 #The starting zorder for all drawing, negative to have the grid on
+
+class WindroseAxes(PolarAxes):
+    """
+
+    Create a windrose axes
+
+    """
+
+    def __init__(self, *args, **kwargs):
+        """
+        See Axes base class for args and kwargs documentation
+        """
+        
+        #Uncomment to have the possibility to change the resolution directly 
+        #when the instance is created
+        #self.RESOLUTION = kwargs.pop('resolution', 100)
+        PolarAxes.__init__(self, *args, **kwargs)
+        self.set_aspect('equal', adjustable='box', anchor='C')
+        self.radii_angle = 67.5
+        self.cla()
+
+
+    def cla(self):
+        """
+        Clear the current axes
+        """
+        PolarAxes.cla(self)
+
+        self.theta_angles = np.arange(0, 360, 45)
+        self.theta_labels = ['E', 'N-E', 'N', 'N-W', 'W', 'S-W', 'S', 'S-E']
+        self.set_thetagrids(angles=self.theta_angles, labels=self.theta_labels)
+
+        self._info = {'dir' : list(),
+                      'bins' : list(),
+                      'table' : list()}
+
+        self.patches_list = list()
+
+
+    def _colors(self, cmap, n):
+        '''
+        Returns a list of n colors based on the colormap cmap
+
+        '''
+        return [cmap(i) for i in np.linspace(0.0, 1.0, n)]
+
+
+    def set_radii_angle(self, **kwargs):
+        """
+        Set the radii labels angle
+        """
+
+        null = kwargs.pop('labels', None)
+        angle = kwargs.pop('angle', None)
+        if angle is None:
+            angle = self.radii_angle
+        self.radii_angle = angle
+        radii = np.linspace(0.1, self.get_rmax(), 6)
+        radii_labels = [ "%.1f" %r for r in radii ]
+        radii_labels[0] = "" #Removing label 0
+        null = self.set_rgrids(radii=radii, labels=radii_labels,
+                               angle=self.radii_angle, **kwargs)
+
+
+    def _update(self):
+        self.set_rmax(rmax=np.max(np.sum(self._info['table'], axis=0)))
+        self.set_radii_angle(angle=self.radii_angle)
+
+
+    def legend(self, loc='lower left', **kwargs):
+        """
+        Sets the legend location and her properties.
+        The location codes are
+
+          'best'         : 0,
+          'upper right'  : 1,
+          'upper left'   : 2,
+          'lower left'   : 3,
+          'lower right'  : 4,
+          'right'        : 5,
+          'center left'  : 6,
+          'center right' : 7,
+          'lower center' : 8,
+          'upper center' : 9,
+          'center'       : 10,
+
+        If none of these are suitable, loc can be a 2-tuple giving x,y
+        in axes coords, ie,
+
+          loc = (0, 1) is left top
+          loc = (0.5, 0.5) is center, center
+
+        and so on.  The following kwargs are supported:
+
+        isaxes=True           # whether this is an axes legend
+        prop = FontProperties(size='smaller')  # the font property
+        pad = 0.2             # the fractional whitespace inside the legend border
+        shadow                # if True, draw a shadow behind legend
+        labelsep = 0.005     # the vertical space between the legend entries
+        handlelen = 0.05     # the length of the legend lines
+        handletextsep = 0.02 # the space between the legend line and legend text
+        axespad = 0.02       # the border between the axes and legend edge
+        """
+
+        def get_handles():
+            handles = list()
+            for p in self.patches_list:
+                if isinstance(p, matplotlib.patches.Polygon) or \
+                isinstance(p, matplotlib.patches.Rectangle):
+                    color = p.get_facecolor()
+                elif isinstance(p, matplotlib.lines.Line2D):
+                    color = p.get_color()
+                else:
+                    raise AttributeError("Can't handle patches")
+                handles.append(Rectangle((0, 0), 0.2, 0.2,
+                    facecolor=color, edgecolor='black'))
+            return handles
+
+        def get_labels():
+            labels = np.copy(self._info['bins'])
+            print labels
+            labels = ["[%.1f : %0.1f[" %(labels[i], labels[i+1]) \
+                      for i in range(len(labels)-1)]
+            return labels
+
+        null = kwargs.pop('labels', None)
+        null = kwargs.pop('handles', None)
+        handles = get_handles()
+        labels = get_labels()
+        print handles
+        labels = [x[1:-1] for x in labels]
+        print labels
+        self.legend_ = matplotlib.legend.Legend(self, handles, labels,
+                                                loc, **kwargs)
+        return self.legend_
+
+
+    def _init_plot(self, dir, var, **kwargs):
+        """
+        Internal method used by all plotting commands
+        """
+        #self.cla()
+        null = kwargs.pop('zorder', None)
+
+        #Init of the bins array if not set
+        bins = kwargs.pop('bins', None)
+        if bins is None:
+            bins = np.linspace(np.min(var), np.max(var), 6)
+        if isinstance(bins, int):
+            bins = np.linspace(np.min(var), np.max(var), bins)
+        bins = np.asarray(bins)
+        nbins = len(bins)
+
+        #Number of sectors
+        nsector = kwargs.pop('nsector', None)
+        if nsector is None:
+            nsector = 16
+
+        #Sets the colors table based on the colormap or the "colors" argument
+        colors = kwargs.pop('colors', None)
+        cmap = kwargs.pop('cmap', None)
+        if colors is not None:
+            if isinstance(colors, str):
+                colors = [colors]*nbins
+            if isinstance(colors, (tuple, list)):
+                if len(colors) != nbins:
+                    raise ValueError("colors and bins must have same length")
+        else:
+            if cmap is None:
+                cmap = cm.jet
+            colors = self._colors(cmap, nbins)
+
+        #Building the angles list
+        angles = np.arange(0, -2*np.pi, -2*np.pi/nsector) + np.pi/2
+
+        normed = kwargs.pop('normed', False)
+        blowto = kwargs.pop('blowto', False)
+
+        #Set the global information dictionnary
+        self._info['dir'], self._info['bins'], self._info['table'] = histogram(dir, var, bins, nsector, normed, blowto)
+
+        return bins, nbins, nsector, colors, angles, kwargs
+
+
+    def contour(self, dir, var, **kwargs):
+        """
+        Plot a windrose in linear mode. For each var bins, a line will be
+        draw on the axes, a segment between each sector (center to center).
+        Each line can be formated (color, width, ...) like with standard plot
+        pylab command.
+
+        Mandatory:
+        * dir : 1D array - directions the wind blows from, North centred
+        * var : 1D array - values of the variable to compute. Typically the wind
+        speeds
+        Optional:
+        * nsector: integer - number of sectors used to compute the windrose
+        table. If not set, nsectors=16, then each sector will be 360/16=22.5°,
+        and the resulting computed table will be aligned with the cardinals
+        points.
+        * bins : 1D array or integer- number of bins, or a sequence of
+        bins variable. If not set, bins=6, then
+            bins=linspace(min(var), max(var), 6)
+        * blowto : bool. If True, the windrose will be pi rotated,
+        to show where the wind blow to (usefull for pollutant rose).
+        * colors : string or tuple - one string color ('k' or 'black'), in this
+        case all bins will be plotted in this color; a tuple of matplotlib
+        color args (string, float, rgb, etc), different levels will be plotted
+        in different colors in the order specified.
+        * cmap : a cm Colormap instance from matplotlib.cm.
+          - if cmap == None and colors == None, a default Colormap is used.
+
+        others kwargs : see help(pylab.plot)
+
+        """
+
+        bins, nbins, nsector, colors, angles, kwargs = self._init_plot(dir, var,
+                                                                       **kwargs)
+
+        #closing lines
+        angles = np.hstack((angles, angles[-1]-2*np.pi/nsector))
+        vals = np.hstack((self._info['table'],
+                         np.reshape(self._info['table'][:,0],
+                                   (self._info['table'].shape[0], 1))))
+        
+        offset = 0
+        for i in range(nbins):
+            val = vals[i,:] + offset
+            offset += vals[i, :]
+            zorder = ZBASE + nbins - i
+            patch = self.plot(angles, val, color=colors[i], zorder=zorder,
+                              **kwargs)
+            self.patches_list.extend(patch)
+        self._update()
+
+
+    def contourf(self, dir, var, **kwargs):
+        """
+        Plot a windrose in filled mode. For each var bins, a line will be
+        draw on the axes, a segment between each sector (center to center).
+        Each line can be formated (color, width, ...) like with standard plot
+        pylab command.
+
+        Mandatory:
+        * dir : 1D array - directions the wind blows from, North centred
+        * var : 1D array - values of the variable to compute. Typically the wind
+        speeds
+        Optional:
+        * nsector: integer - number of sectors used to compute the windrose
+        table. If not set, nsectors=16, then each sector will be 360/16=22.5°,
+        and the resulting computed table will be aligned with the cardinals
+        points.
+        * bins : 1D array or integer- number of bins, or a sequence of
+        bins variable. If not set, bins=6, then
+            bins=linspace(min(var), max(var), 6)
+        * blowto : bool. If True, the windrose will be pi rotated,
+        to show where the wind blow to (usefull for pollutant rose).
+        * colors : string or tuple - one string color ('k' or 'black'), in this
+        case all bins will be plotted in this color; a tuple of matplotlib
+        color args (string, float, rgb, etc), different levels will be plotted
+        in different colors in the order specified.
+        * cmap : a cm Colormap instance from matplotlib.cm.
+          - if cmap == None and colors == None, a default Colormap is used.
+
+        others kwargs : see help(pylab.plot)
+
+        """
+
+        bins, nbins, nsector, colors, angles, kwargs = self._init_plot(dir, var,
+                                                                       **kwargs)
+        null = kwargs.pop('facecolor', None)
+        null = kwargs.pop('edgecolor', None)
+        
+        #closing lines
+        angles = np.hstack((angles, angles[-1]-2*np.pi/nsector))
+        vals = np.hstack((self._info['table'],
+                         np.reshape(self._info['table'][:,0],
+                                   (self._info['table'].shape[0], 1))))
+        offset = 0
+        for i in range(nbins):
+            val = vals[i,:] + offset
+            offset += vals[i, :]
+            zorder = ZBASE + nbins - i
+            xs, ys = poly_between(angles, 0, val)
+            patch = self.fill(xs, ys, facecolor=colors[i],
+                              edgecolor=colors[i], zorder=zorder, **kwargs)
+            self.patches_list.extend(patch)
+
+
+    def bar(self, dir, var, **kwargs):
+        """
+        Plot a windrose in bar mode. For each var bins and for each sector,
+        a colored bar will be draw on the axes.
+
+        Mandatory:
+        * dir : 1D array - directions the wind blows from, North centred
+        * var : 1D array - values of the variable to compute. Typically the wind
+        speeds
+        Optional:
+        * nsector: integer - number of sectors used to compute the windrose
+        table. If not set, nsectors=16, then each sector will be 360/16=22.5°,
+        and the resulting computed table will be aligned with the cardinals
+        points.
+        * bins : 1D array or integer- number of bins, or a sequence of
+        bins variable. If not set, bins=6 between min(var) and max(var).
+        * blowto : bool. If True, the windrose will be pi rotated,
+        to show where the wind blow to (usefull for pollutant rose).
+        * colors : string or tuple - one string color ('k' or 'black'), in this
+        case all bins will be plotted in this color; a tuple of matplotlib
+        color args (string, float, rgb, etc), different levels will be plotted
+        in different colors in the order specified.
+        * cmap : a cm Colormap instance from matplotlib.cm.
+          - if cmap == None and colors == None, a default Colormap is used.
+        edgecolor : string - The string color each edge bar will be plotted.
+        Default : no edgecolor
+        * opening : float - between 0.0 and 1.0, to control the space between
+        each sector (1.0 for no space)
+
+        """
+
+        bins, nbins, nsector, colors, angles, kwargs = self._init_plot(dir, var,
+                                                                      **kwargs)
+        print bins
+        null = kwargs.pop('facecolor', None)
+        edgecolor = kwargs.pop('edgecolor', None)
+        if edgecolor is not None:
+            if not isinstance(edgecolor, str):
+                raise ValueError('edgecolor must be a string color')
+        opening = kwargs.pop('opening', None)
+        if opening is None:
+            opening = 0.8
+        dtheta = 2*np.pi/nsector
+        opening = dtheta*opening
+
+        for j in range(nsector):
+            offset = 0
+            for i in range(nbins):
+                if i > 0:
+                    offset += self._info['table'][i-1, j]
+                val = self._info['table'][i, j]
+                zorder = ZBASE + nbins - i
+                patch = Rectangle((angles[j]-opening/2, offset), opening, val,
+                    facecolor=colors[i], edgecolor=edgecolor, zorder=zorder,
+                    **kwargs)
+                self.add_patch(patch)
+                if j == 0:
+                    self.patches_list.append(patch)
+        self._update()
+
+
+    def box(self, dir, var, **kwargs):
+        """
+        Plot a windrose in proportional bar mode. For each var bins and for each
+        sector, a colored bar will be draw on the axes.
+
+        Mandatory:
+        * dir : 1D array - directions the wind blows from, North centred
+        * var : 1D array - values of the variable to compute. Typically the wind
+        speeds
+        Optional:
+        * nsector: integer - number of sectors used to compute the windrose
+        table. If not set, nsectors=16, then each sector will be 360/16=22.5°,
+        and the resulting computed table will be aligned with the cardinals
+        points.
+        * bins : 1D array or integer- number of bins, or a sequence of
+        bins variable. If not set, bins=6 between min(var) and max(var).
+        * blowto : bool. If True, the windrose will be pi rotated,
+        to show where the wind blow to (usefull for pollutant rose).
+        * colors : string or tuple - one string color ('k' or 'black'), in this
+        case all bins will be plotted in this color; a tuple of matplotlib
+        color args (string, float, rgb, etc), different levels will be plotted
+        in different colors in the order specified.
+        * cmap : a cm Colormap instance from matplotlib.cm.
+          - if cmap == None and colors == None, a default Colormap is used.
+        edgecolor : string - The string color each edge bar will be plotted.
+        Default : no edgecolor
+
+        """
+
+        bins, nbins, nsector, colors, angles, kwargs = self._init_plot(dir, var,
+                                                                       **kwargs)
+        null = kwargs.pop('facecolor', None)
+        edgecolor = kwargs.pop('edgecolor', None)
+        if edgecolor is not None:
+            if not isinstance(edgecolor, str):
+                raise ValueError('edgecolor must be a string color')
+        opening = np.linspace(0.0, np.pi/16, nbins)
+
+        for j in range(nsector):
+            offset = 0
+            for i in range(nbins):
+                if i > 0:
+                    offset += self._info['table'][i-1, j]
+                val = self._info['table'][i, j]
+                zorder = ZBASE + nbins - i
+                patch = Rectangle((angles[j]-opening[i]/2, offset), opening[i],
+                    val, facecolor=colors[i], edgecolor=edgecolor,
+                    zorder=zorder, **kwargs)
+                self.add_patch(patch)
+                if j == 0:
+                    self.patches_list.append(patch)
+        self._update()
+
+def histogram(dir, var, bins, nsector, normed=False, blowto=False):
+    """
+    Returns an array where, for each sector of wind
+    (centred on the north), we have the number of time the wind comes with a
+    particular var (speed, polluant concentration, ...).
+    * dir : 1D array - directions the wind blows from, North centred
+    * var : 1D array - values of the variable to compute. Typically the wind
+        speeds
+    * bins : list - list of var category against we're going to compute the table
+    * nsector : integer - number of sectors
+    * normed : boolean - The resulting table is normed in percent or not.
+    * blowto : boolean - Normaly a windrose is computed with directions
+    as wind blows from. If true, the table will be reversed (usefull for
+    pollutantrose)
+
+    """
+
+    if len(var) != len(dir):
+        raise ValueError, "var and dir must have same length"
+
+    angle = 360./nsector
+
+    dir_bins = np.arange(-angle/2 ,360.+angle, angle, dtype=np.float)
+    dir_edges = dir_bins.tolist()
+    dir_edges.pop(-1)
+    dir_edges[0] = dir_edges.pop(-1)
+    dir_bins[0] = 0.
+
+    var_bins = bins.tolist()
+    var_bins.append(np.inf)
+
+    if blowto:
+        dir = dir + 180.
+        dir[dir>=360.] = dir[dir>=360.] - 360
+
+    table = histogram2d(x=var, y=dir, bins=[var_bins, dir_bins],
+                          normed=False)[0]
+    # add the last value to the first to have the table of North winds
+    table[:,0] = table[:,0] + table[:,-1]
+    # and remove the last col
+    table = table[:, :-1]
+    if normed:
+        table = table*100/table.sum()
+
+    return dir_edges, var_bins, table
+
+
+def wrcontour(dir, var, **kwargs):
+    fig = plt.figure()
+    rect = [0.1, 0.1, 0.8, 0.8]
+    ax = WindroseAxes(fig, rect)
+    fig.add_axes(ax)
+    ax.contour(dir, var, **kwargs)
+    l = ax.legend(axespad=-0.10)
+    plt.setp(l.get_texts(), fontsize=8)
+    plt.draw()
+    plt.show()
+    return ax
+
+def wrcontourf(dir, var, **kwargs):
+    fig = plt.figure()
+    rect = [0.1, 0.1, 0.8, 0.8]
+    ax = WindroseAxes(fig, rect)
+    fig.add_axes(ax)
+    ax.contourf(dir, var, **kwargs)
+    l = ax.legend(axespad=-0.10)
+    plt.setp(l.get_texts(), fontsize=8)
+    plt.draw()
+    plt.show()
+    return ax
+
+def wrbox(dir, var, **kwargs):
+    fig = plt.figure()
+    rect = [0.1, 0.1, 0.8, 0.8]
+    ax = WindroseAxes(fig, rect)
+    fig.add_axes(ax)
+    ax.box(dir, var, **kwargs)
+    l = ax.legend(axespad=-0.10)
+    plt.setp(l.get_texts(), fontsize=8)
+    plt.draw()
+    plt.show()
+    return ax
+
+def wrbar(dir, var, **kwargs):
+    fig = plt.figure()
+    rect = [0.1, 0.1, 0.8, 0.8]
+    ax = WindroseAxes(fig, rect)
+    fig.add_axes(ax)
+    ax.bar(dir, var, **kwargs)
+    l = ax.legend(axespad=-0.10)
+    plt.setp(l.get_texts(), fontsize=8)
+    plt.draw()
+    plt.show()
+    return ax
+
+def clean(dir, var):
+    '''
+    Remove masked values in the two arrays, where if a direction data is masked,
+    the var data will also be removed in the cleaning process (and vice-versa)
+    '''
+    dirmask = dir.mask==False
+    varmask = var.mask==False
+    ind = dirmask*varmask
+    return dir[ind], var[ind]
+
+if __name__=='__main__':
+    from pylab import figure, show, setp, random, grid, draw
+    vv=random(500)*6
+    dv=random(500)*360
+    fig = figure(figsize=(8, 8), dpi=80, facecolor='w', edgecolor='w')
+    rect = [0.1, 0.1, 0.8, 0.8]
+    ax = WindroseAxes(fig, rect, axisbg='w')
+    fig.add_axes(ax)
+
+#    ax.contourf(dv, vv, bins=np.arange(0,8,1), cmap=cm.hot)
+#    ax.contour(dv, vv, bins=np.arange(0,8,1), colors='k')
+#    ax.bar(dv, vv, normed=True, opening=0.8, edgecolor='white')
+    ax.box(dv, vv, normed=True)
+    l = ax.legend(axespad=-0.10)
+    setp(l.get_texts(), fontsize=8)
+    draw()
+    #print ax._info
+    show()
+
+
+
+
+
+