# coding=utf-8
#-----------------------------------------------------
# Author: Yaqiang Wang
# Date: 2017-3-25
# Purpose: MeteoInfoLab axes module
# Note: Jython
#-----------------------------------------------------

from org.meteoinfo.chart import Location, ChartWindArrow, ChartText, LegendPosition, \
    ChartLegend, ChartColorBar, AspectType
from org.meteoinfo.chart.plot import Plot2D, PolarPlot, PlotOrientation
from org.meteoinfo.chart.graphic import GraphicFactory
from org.meteoinfo.common import XAlign, YAlign
from org.meteoinfo.chart.axis import Axis, LonLatAxis, TimeAxis, LogAxis
from org.meteoinfo.geo.legend import LegendManage
from org.meteoinfo.geometry.legend import BarBreak, PolygonBreak, PolylineBreak, \
    PointBreak, LineStyles, PointStyle, LegendScheme, LegendType
from org.meteoinfo.geometry.shape import ShapeTypes
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection
from org.meteoinfo.common import MIMath, Extent
from org.meteoinfo.geo.layer import MapLayer

from java.awt import Font, Color, BasicStroke
from java.awt.image import BufferedImage
from java.util import HashMap

import numbers
import datetime
import math

import mipylib.numeric as np
from mipylib.numeric.core import DimArray, NDArray
from mipylib.geolib.milayer import MILayer, MIXYListData
import plotutil
import colors
import mipylib.miutil as miutil

__all__ = ['Axes','PolarAxes']

class Axes(object):
    """
    Axes with Cartesian coordinate.
    """

    def __init__(self, *args, **kwargs):
        axes = kwargs.pop('axes', None)
        self._set_plot(axes)
        
        figure = kwargs.pop('figure', None)
        self.figure = figure
        
        if len(args) > 0:
            position = args[0]
        else:
            position = kwargs.pop('position', None)    
        outerposition = kwargs.pop('outerposition', None)
        if position is None:
            position = [0.13, 0.11, 0.775, 0.815]
            self.active_outerposition(True)
        else:        
            self.active_outerposition(False)        
        self.set_position(position)   
        if not outerposition is None:
            self.set_outerposition(outerposition)
            self.active_outerposition(True)
        units = kwargs.pop('units', None)
        if not units is None:
            self._axes.setUnits(units)
            
        aspect = kwargs.pop('aspect', 'auto')
        axis = kwargs.pop('axis', None)
        if axis is None:
            axis = kwargs.pop('axison', True)
        b_axis = self.get_axis(Location.BOTTOM)
        l_axis = self.get_axis(Location.LEFT)
        t_axis = self.get_axis(Location.TOP)
        r_axis = self.get_axis(Location.RIGHT)
        if axis:
            bottomaxis = kwargs.pop('bottomaxis', True)
            leftaxis = kwargs.pop('leftaxis', True)
            topaxis = kwargs.pop('topaxis', True)
            rightaxis = kwargs.pop('rightaxis', True)
        else:
            bottomaxis = False
            leftaxis = False
            topaxis = False
            rightaxis = False
        xreverse = kwargs.pop('xreverse', False)
        yreverse = kwargs.pop('yreverse', False)
        xaxistype = kwargs.pop('xaxistype', None)
        bgcobj = kwargs.pop('bgcolor', None)        
        
        if aspect == 'equal':
            self._axes.setAspectType(AspectType.EQUAL)
        else:
            if isinstance(aspect, (int, float)):
                self._axes.setAspect(aspect)
                self._axes.setAspectType(AspectType.RATIO)
        if not bottomaxis:
            b_axis.setVisible(False)
        if not leftaxis:
            l_axis.setVisible(False)
        if not topaxis:
            t_axis.setVisible(False)
        if not rightaxis:
            r_axis.setVisible(False)
        if xreverse:
            b_axis.setInverse(True)
            t_axis.setInverse(True)
        if yreverse:
            l_axis.setInverse(True)
            r_axis.setInverse(True)        
        if not xaxistype is None:
            self.set_xaxis_type(xaxistype)
        bgcolor = plotutil.getcolor(bgcobj)
        self._axes.setBackground(bgcolor)
        tickline = kwargs.pop('tickline', None)
        if not tickline is None:
            b_axis.setDrawTickLine(tickline)
            t_axis.setDrawTickLine(tickline)
            l_axis.setDrawTickLine(tickline)
            r_axis.setDrawTickLine(tickline)
        tickfontname = kwargs.pop('tickfontname', 'Arial')
        tickfontsize = kwargs.pop('tickfontsize', 14)
        tickbold = kwargs.pop('tickbold', False)
        if tickbold:
            font = Font(tickfontname, Font.BOLD, tickfontsize)
        else:
            font = Font(tickfontname, Font.PLAIN, tickfontsize)
        self._axes.setAxisLabelFont(font)
        clip = kwargs.pop('clip', None)
        if not clip is None:
            self._axes.setClip(clip)
    
    def _set_plot(self, plot):
        """
        Set plot.
        
        :param plot: (*Plot2D*) Plot.
        """
        if plot is None:
            self._axes = Plot2D()
        else:
            self._axes = plot
    
    @property
    def axestype(self):
        return 'cartesian'

    @property
    def ndim(self):
        """
        Dimension number property
        """
        return 2
    
    def get_type(self):
        """
        Get axes type
        
        :returns: Axes type
        """
        return self._axes.getPlotType()
            
    def get_position(self):
        """
        Get axes position             

        :returns: Axes position [left, bottom, width, height] in normalized (0, 1) units
        """
        pos = self._axes.getPosition()
        return [pos.x, pos.y, pos.width, pos.height]
        
    def set_position(self, pos):
        """
        Set axes position
        
        :param pos: (*list*) Axes position specified by *position=* [left, bottom, width,
            height] in normalized (0, 1) units
        """
        self._axes.setPosition(pos)
        
    def get_outerposition(self):
        """
        Get axes outer position
        
        :returns: Axes outer position [left, bottom, width, height] in normalized (0, 1) units
        """
        pos = self._axes.getOuterPosition()
        return [pos.x, pos.y, pos.width, pos.height]
        
    def set_outerposition(self, pos):
        """
        Set axes outer position
        
        :param pos: (*list*) Axes outer position specified by *outerposition=* [left, bottom, width,
            height] in normalized (0, 1) units
        """
        self._axes.setOuterPosition(pos)
        
    def active_outerposition(self, active):
        """
        Set axes outer position active or not.
        
        :param active: (*boolean*) Active or not
        """
        self._axes.setOuterPosActive(active)
    
    def get_axis(self, loc):
        """
        Get axis by location.
        
        :param loc: (*Location*) Location enum.
        
        :returns: Axis
        """
        return self._axes.getAxis(loc)

    def set_aspect(self, aspect):
        """
        Set axes aspect

        :param aspect: (*string or number*) Axes aspect ['equal' | 'auto'].
        """
        if aspect == 'equal':
            self._axes.setAspectType(AspectType.EQUAL)
        else:
            if isinstance(aspect, (int, float)):
                self._axes.setAspect(aspect)
                self._axes.setAspectType(AspectType.RATIO)
            else:
                self._axes.setAspectType(AspectType.AUTO)

    def set_clip(self, clip):
        """
        Set axes clip or not

        :param clip: (*bool*) Clip or not
        """
        self._axes.setClip(clip)
        
    def get_title(self, loc='center'):
        """
        Get title            

        :param loc: (*string*) Which title to get ['center' | 'left' | 'right'],
            default to 'center'.
        
        :returns: The title.
        """
        if loc == 'left':
            return self.aexs.getLeftTitle()
        elif loc == 'right':
            return self._axes.getRightTitle()
        else:
            return self._axes.getTitle()
        
    def set_title(self, label, loc='center', fontname=None, fontsize=14, bold=True, color='black', **kwargs):
        """
        Set a title of the current axes.
        
        :param label: (*string*) Title string.
        :param loc: (*string') Which title to set ['center' | 'left' | 'right'],
            default to 'center'.
        :param fontname: (*string*) Font name. Default is ``None``, using ``Arial`` .
        :param fontsize: (*int*) Font size. Default is ``14`` .
        :param bold: (*boolean*) Is bold font or not. Default is ``True`` .
        :param color: (*color*) Title string color. Default is ``black`` .  
        :param linespace: (*int*) Line space of multiple line title.
        """
        exfont = False
        if fontname is None:
            fontname = 'Arial'
        else:
            exfont = True
            
        if bold:
            font = Font(fontname, Font.BOLD, fontsize)
        else:
            font = Font(fontname, Font.PLAIN, fontsize)
        c = plotutil.getcolor(color)
        title = ChartText(label, font)
        title.setXAlign(loc)
        title.setUseExternalFont(exfont)
        title.setColor(c)
        linespace = kwargs.pop('linespace', None)
        if not linespace is None:
            title.setLineSpace(linespace)
        
        if loc == 'left':
            self._axes.setLeftTitle(title)
        elif loc == 'right':
            self._axes.setRightTitle(title)
        else:
            self._axes.setTitle(title)
            
        return title
            
    def set_xlabel(self, label, **kwargs):
        """
        Set the x axis label of the current axes.
        
        :param label: (*string*) Label string.
        :param fontname: (*string*) Font name. Default is ``Arial`` .
        :param fontsize: (*int*) Font size. Default is ``14`` .
        :param bold: (*boolean*) Is bold font or not. Default is ``True`` .
        :param color: (*color*) Label string color. Default is ``black`` .
        """
        if not kwargs.has_key('xalign'):
            kwargs['xalign'] = 'center'
        if not kwargs.has_key('yalign'):
            kwargs['yalign'] = 'top'
        ctext = plotutil.text(0, 0, label, **kwargs)
        axis = self._axes.getXAxis()
        axis.setLabel(ctext)
        axis.setDrawLabel(True)
        if self.axestype != '3d':
            axis_t = self._axes.getAxis(Location.TOP)
            text = ctext.clone()
            text.setXAlign('center')
            text.setYAlign('bottom')
            axis_t.setLabel(text)
    
    def set_ylabel(self, label, **kwargs):
        """
        Set the y axis label of the current axes.
        
        :param label: (*string*) Label string.
        :param fontname: (*string*) Font name. Default is ``Arial`` .
        :param fontsize: (*int*) Font size. Default is ``14`` .
        :param bold: (*boolean*) Is bold font or not. Default is ``True`` .
        :param color: (*color*) Label string color. Default is ``black`` .
        """
        if not kwargs.has_key('xalign'):
            kwargs['xalign'] = 'center'
        if not kwargs.has_key('yalign'):
            kwargs['yalign'] = 'bottom'
        if not kwargs.has_key('rotation'):
            kwargs['rotation'] = 90
        ctext = plotutil.text(0, 0, label, **kwargs)
        axis = self._axes.getYAxis()
        axis.setLabel(ctext)
        axis.setDrawLabel(True)
        if self.axestype != '3d':
            axis_r = self._axes.getAxis(Location.RIGHT)
            text = ctext.clone()            
            text.setXAlign('left')
            text.setYAlign('center')
            axis_r.setLabel(text)
    
    def get_xticks(self):
        """
        Get x axis tick locations.
        """
        axis = self._axes.getXAxis()
        axis.updateTickLabels()
        return axis.getTickLocations()
        
    def set_xticks(self, locs):
        """
        Set x axis tick locations.
        """
        axis = self._axes.getXAxis()
        if isinstance(locs, (NDArray, DimArray)):
            locs = locs.aslist()
        axis.setTickLocations(locs)
        
        if self.axestype == '3d':
            axis_t = None
        else:
            axis_t = self._axes.getAxis(Location.TOP)
        if not axis_t is None:
            axis_t.setTickLocations(locs)
        
    def get_yticks(self):
        """
        Get y axis tick locations.
        """
        axis = self._axes.getYAxis()
        axis.updateTickLabels()
        return axis.getTickLocations()
        
    def set_yticks(self, locs):
        """
        Set y axis tick locations.
        """
        axis = self._axes.getYAxis()
        if isinstance(locs, NDArray):
            locs = locs.aslist()
        axis.setTickLocations(locs)
        
        if self.axestype == '3d':
            axis_r = None
        else:
            axis_r = self._axes.getAxis(Location.RIGHT)
        if not axis_r is None:
            axis_r.setTickLocations(locs)
        
    def get_xticklabels(self):
        """
        Get x axis tick labels.
        """
        axis = self._axes.getXAxis()
        axis.updateTickLabels()
        return axis.getTickLabelText()
        
    def set_xticklabels(self, labels, **kwargs):
        """
        Set x axis tick labels.
        """
        axis = self._axes.getXAxis()
        if self.axestype == '3d':
            axis_t = None
        else:
            axis_t = self._axes.getAxis(Location.TOP)
            
        if not labels is None:
            if isinstance(labels, (NDArray, DimArray)):
                labels = labels.aslist()
            if isinstance(labels[0], (int, long, float)):
                axis.setTickLabels_Number(labels)
            else:
                axis.setTickLabelText(labels)                   
            
            if not axis_t is None:
                if isinstance(labels[0], (int, long, float)):
                    axis_t.setTickLabels_Number(labels)
                else:
                    axis_t.setTickLabelText(labels)
        
        fontname = kwargs.pop('fontname', axis.getTickLabelFont().getName())
        fontsize = kwargs.pop('fontsize', axis.getTickLabelFont().getSize())
        bold =kwargs.pop('bold', axis.getTickLabelFont().isBold())
        if bold:
            font = Font(fontname, Font.BOLD, fontsize)
        else:
            font = Font(fontname, Font.PLAIN, fontsize)
        color = kwargs.pop('color', axis.getTickLabelColor())
        c = plotutil.getcolor(color)
        angle = kwargs.pop('rotation', 0)
        if angle == 'vertical':
            angle = 90
        axis.setTickLabelFont(font)
        axis.setTickLabelColor(c)
        axis.setTickLabelAngle(angle)
        if not axis_t is None:
            axis_t.setTickLabelFont(font)
            axis_t.setTickLabelColor(c)
            axis_t.setTickLabelAngle(angle)
            
    def get_yticklabels(self):
        """
        Get y axis tick labels.
        """
        axis = self._axes.getYAxis()
        axis.updateTickLabels()
        return axis.getTickLabelText()
        
    def set_yticklabels(self, labels, **kwargs):
        """
        Set y axis tick labels.
        """
        axis = self._axes.getYAxis()
        if self.axestype == '3d':
            axis_r = None
        else:
            axis_r = self._axes.getAxis(Location.RIGHT)
            
        if not labels is None:
            if isinstance(labels, (NDArray, DimArray)):
                labels = labels.aslist()
            if isinstance(labels[0], (int, long, float)):
                axis.setTickLabels_Number(labels)
            else:
                axis.setTickLabelText(labels)        
        
            if not axis_r is None:
                if isinstance(labels[0], (int, long, float)):
                    axis_r.setTickLabels_Number(labels)
                else:
                    axis_r.setTickLabelText(labels)
                
        fontname = kwargs.pop('fontname', axis.getTickLabelFont().getName())
        fontsize = kwargs.pop('fontsize', axis.getTickLabelFont().getSize())
        bold =kwargs.pop('bold', axis.getTickLabelFont().isBold())
        if bold:
            font = Font(fontname, Font.BOLD, fontsize)
        else:
            font = Font(fontname, Font.PLAIN, fontsize)
        color = kwargs.pop('color', axis.getTickLabelColor())
        c = plotutil.getcolor(color)
        angle = kwargs.pop('rotation', 0)
        if angle == 'vertical':
            angle = 90
        axis.setTickLabelFont(font)
        axis.setTickLabelColor(c)
        axis.setTickLabelAngle(angle)
        if not axis_r is None:
            axis_r.setTickLabelFont(font)
            axis_r.setTickLabelColor(c)
            axis_r.setTickLabelAngle(angle)
            
    def set_xaxis_type(self, axistype, timetickformat=None):
        """
        Set x axis type.
        
        :param axistype: (*string*) Axis type ['lon' | 'lat' | 'time' | 'log'].
        :param timetickformat: (*string*) Time tick label format.
        """
        ax = self._axes
        b_axis = ax.getAxis(Location.BOTTOM)
        t_axis = ax.getAxis(Location.TOP)
        if axistype == 'lon':
            if not isinstance(b_axis, LonLatAxis):
                b_axis = LonLatAxis(b_axis)
            b_axis.setLongitude(True)
            ax.setAxis(b_axis, Location.BOTTOM)
            if not isinstance(t_axis, LonLatAxis):
                t_axis = LonLatAxis(t_axis)
            t_axis.setLongitude(True)
            ax.setAxis(t_axis, Location.TOP)
        elif axistype == 'lat':
            if not isinstance(b_axis, LonLatAxis):
                b_axis = LonLatAxis(b_axis)
            b_axis.setLongitude(False)
            ax.setAxis(b_axis, Location.BOTTOM)
            if not isinstance(t_axis, LonLatAxis):
                t_axis = LonLatAxis(t_axis)
            t_axis.setLongitude(False)
            ax.setAxis(t_axis, Location.TOP)
        elif axistype == 'time':
            if not isinstance(b_axis, TimeAxis):
                b_axis = TimeAxis(b_axis)
            ax.setAxis(b_axis, Location.BOTTOM)
            if not isinstance(t_axis, TimeAxis):
                t_axis = TimeAxis(t_axis)
            ax.setAxis(t_axis, Location.TOP)
            if not timetickformat is None:
                b_axis.setTimeFormat(timetickformat)
                t_axis.setTimeFormat(timetickformat)
        elif axistype == 'log':
            if not isinstance(b_axis, LogAxis):
                b_axis = LogAxis(b_axis)
                b_axis.setMinorTickNum(10)
            ax.setAxis(b_axis, Location.BOTTOM)
            if not isinstance(t_axis, LogAxis):
                t_axis = LogAxis(t_axis)
                t_axis.setMinorTickNum(10)
            ax.setAxis(t_axis, Location.TOP)   
        else:
            b_axis = Axis(ax.getAxis(Location.BOTTOM))
            ax.setAxis(b_axis, Location.BOTTOM)
            t_axis = Axis(ax.getAxis(Location.TOP))
            ax.setAxis(t_axis, Location.TOP)
                    
    def set_yaxis_type(self, axistype, timetickformat=None):
        """
        Set y axis type.
        
        :param axistype: (*string*) Axis type ['lon' | 'lat' | 'time' | 'log'].
        :param timetickformat: (*string*) Time tick label format.
        """
        ax = self._axes
        if axistype == 'lon':
            b_axis = LonLatAxis(ax.getAxis(Location.LEFT))
            #b_axis.setLabel('Longitude')
            b_axis.setLongitude(True)
            ax.setAxis(b_axis, Location.LEFT)
            t_axis = LonLatAxis(ax.getAxis(Location.RIGHT))
            #t_axis.setLabel('Longitude')
            t_axis.setLongitude(True)
            ax.setAxis(t_axis, Location.RIGHT)
        elif axistype == 'lat':
            b_axis = LonLatAxis(ax.getAxis(Location.LEFT))
            #b_axis.setLabel('Latitude')
            b_axis.setLongitude(False)
            ax.setAxis(b_axis, Location.LEFT)
            t_axis = LonLatAxis(ax.getAxis(Location.RIGHT))
            #t_axis.setLabel('Latitude')
            t_axis.setLongitude(False)
            ax.setAxis(t_axis, Location.RIGHT)
        elif axistype == 'time':
            b_axis = TimeAxis(ax.getAxis(Location.LEFT))
            ax.setAxis(b_axis, Location.LEFT)
            t_axis = TimeAxis(ax.getAxis(Location.RIGHT))
            ax.setAxis(t_axis, Location.RIGHT)
            if not timetickformat is None:
                ax.getAxis(Location.LEFT).setTimeFormat(timetickformat)
                ax.getAxis(Location.RIGHT).setTimeFormat(timetickformat)
        elif axistype == 'log':
            l_axis = LogAxis(ax.getAxis(Location.LEFT))
            #l_axis.setLabel('Log')
            l_axis.setMinorTickNum(10)
            ax.setAxis(l_axis, Location.LEFT)
            r_axis = LogAxis(ax.getAxis(Location.RIGHT))
            #r_axis.setLabel('Log')
            r_axis.setMinorTickNum(10)
            ax.setAxis(r_axis, Location.RIGHT)
        else:
            l_axis = Axis(ax.getAxis(Location.LEFT))
            ax.setAxis(l_axis, Location.LEFT)
            r_axis = Axis(ax.getAxis(Location.RIGHT))
            ax.setAxis(r_axis, Location.RIGHT)
        
    def axis(self, limits):
        """
        Sets the min and max of the x and y axes, with ``[xmin, xmax, ymin, ymax]`` .
        
        :param limits: (*list*) Min and max of the x and y axes.
        """
        if len(limits) == 4:
            xmin = limits[0]
            xmax = limits[1]
            ymin = limits[2]
            ymax = limits[3]
            extent = Extent(xmin, xmax, ymin, ymax)
            self._axes.setDrawExtent(extent)
            #self._axes.setExtent(extent.clone())
            self._axes.setFixDrawExtent(True)
            return True
        else:
            print('The limits parameter must be a list with 4 elements: xmin, xmax, ymin, ymax!')
            return None
            
    def get_xlim(self):
        """
        Get the *x* limits of the current axes.
        
        :returns: (*tuple*) x limits.
        """
        extent = self._axes.getDrawExtent()
        return extent.minX, extent.maxX
            
    def set_xlim(self, xmin, xmax):
        """
        Set the *x* limits of the current axes.
        
        :param xmin: (*float*) Minimum limit of the x axis.
        :param xmax: (*float*) Maximum limit of the x axis.
        """
        if isinstance(xmin, datetime.datetime):
            xmin = miutil.date2num(xmin)
        if isinstance(xmax, datetime.datetime):
            xmax = miutil.date2num(xmax)    
            
        extent = self._axes.getDrawExtent()
        extent.minX = xmin
        extent.maxX = xmax
        self._axes.setDrawExtent(extent)
        self._axes.setExtent(extent.clone())
        self._axes.setFixDrawExtent(True)

    def get_ylim(self):
        """
        Get the *y* limits of the current axes.
        
        :returns: (*tuple*) y limits.
        """
        extent = self._axes.getDrawExtent()
        return extent.minY, extent.maxY
            
    def set_ylim(self, ymin, ymax):
        """
        Set the *yt* limits of the current axes.
        
        :param ymin: (*float*) Minimum limit of the y axis.
        :param ymax: (*float*) Maximum limit of the y axis.
        """
        if isinstance(ymin, datetime.datetime):
            ymin = miutil.date2num(ymin)
        if isinstance(ymax, datetime.datetime):
            ymax = miutil.date2num(ymax)    
            
        extent = self._axes.getDrawExtent()
        extent.minY = ymin
        extent.maxY = ymax
        self._axes.setDrawExtent(extent)
        self._axes.setExtent(extent.clone())
        self._axes.setFixDrawExtent(True)
        
    def twinx(self):
        """
        Make a second axes that shares the x-axis. The new axes will overlay *ax*. The ticks 
        for *ax2* will be placed on the right, and the *ax2* instance is returned.
        
        :returns: The second axes
        """
        self._axes.getAxis(Location.RIGHT).setVisible(False)
        self._axes.setSameShrink(True)
        ax2 = Axes()
        ax2._axes.setSameShrink(True)
        ax2._axes.setPosition(self.get_position())
        ax2._axes.setOuterPosActive(self._axes.isOuterPosActive())
        ax2._axes.getAxis(Location.BOTTOM).setVisible(False)
        ax2._axes.getAxis(Location.LEFT).setVisible(False)
        ax2._axes.getAxis(Location.TOP).setVisible(False)
        axis = ax2._axes.getAxis(Location.RIGHT)
        axis.setDrawTickLine(True)
        axis.setDrawTickLabel(True)
        axis.setDrawLabel(True)
        return ax2
        
    def twiny(self):
        """
        Make a second axes that shares the y-axis. The new axes will overlay *ax*. The ticks 
        for *ax2* will be placed on the top, and the *ax2* instance is returned.
        
        :returns: The second axes
        """
        self._axes.getAxis(Location.TOP).setVisible(False)
        self._axes.setSameShrink(True)
        ax2 = Axes()
        ax2._axes.setSameShrink(True)
        ax2._axes.setPosition(self.get_position())
        ax2._axes.setOuterPosActive(self._axes.isOuterPosActive())
        ax2._axes.getAxis(Location.BOTTOM).setVisible(False)
        ax2._axes.getAxis(Location.LEFT).setVisible(False)
        ax2._axes.getAxis(Location.RIGHT).setVisible(False)
        axis = ax2._axes.getAxis(Location.TOP)
        axis.setDrawTickLine(True)
        axis.setDrawTickLabel(True)
        axis.setDrawLabel(True)
        return ax2

    def xaxis(self, **kwargs):
        """
        Set x-axis of the axes.
        
        :param color: (*Color*) Color of the axis. Default is `black`.
        :param position: (*tuple*) Axis position specified by a 2 tuple of (position type, amount). 
            The position types are ['outerward' | 'axes' | 'data'].
        :param shift: (*int) Axis shif along x direction. Units are pixel. Default is 0.
        :param visible: (*bool*) Set axis visible or not, Default is `None`.
        :param linewidth: (*float*) Line width of the axis.
        :param linestyle: (*string*) Line style of the axis.
        :param tickline: (*boolean*) Draw tick line or not.
        :param tickwidth: (*float*) Tick line width.
        :param ticklength: (*float*) Tick line length.
        :param ticklabel: (*bool*) Draw tick label or not.
        :param minortick: (*bool*) Draw minor tick line or not.
        :param minorticknum: (*int*) Minor tick line number between two adjacent major tick lines.
        :param tickin: (*bool*) Tick lines are plot inside or outside the axes.
        :param axistype: (*string*) Axis type ['normal' | 'lon' | 'lat' | 'time' | 'log'].
        :param timetickformat: (*string*) Time tick label format, only valid with time axis.
        :param tickfontname: (*string*) Tick label font name.
        :param tickfontsize: (*int*) Tick label font size.
        :param tickbold: (*bool*) Tick label font is bold or not.
        :param tickavoidcoll: (*bool*) Whether avoid collision of tick labels. Default is `True`.
        :param location: (*string*) Locations of the axis ['both' | 'top' | 'bottom'].
        """
        visible = kwargs.pop('visible', None)
        position = kwargs.pop('position', None)
        if position == 'center':
            position = ['axes', 0.5]
        elif position == 'zero':
            position = ['data', 0]
        shift = kwargs.pop('shift', None)
        color = kwargs.pop('color', None)
        if not color is None:
            color = plotutil.getcolor(color)
        tickcolor = kwargs.pop('tickcolor', None)
        if not tickcolor is None:
            tickcolor = plotutil.getcolor(tickcolor)
        linewidth = kwargs.pop('linewidth', None)
        linestyle = kwargs.pop('linestyle', None)
        tickline = kwargs.pop('tickline', None)
        tickline = kwargs.pop('tickvisible', tickline)
        tickwidth = kwargs.pop('tickwidth', None)
        ticklength = kwargs.pop('ticklength', None)
        ticklabel = kwargs.pop('ticklabel', None)
        minortick = kwargs.pop('minortick', None)
        minorticknum = kwargs.pop('minorticknum', None)
        tickin = kwargs.pop('tickin', None)
        axistype = kwargs.pop('axistype', None)
        timetickformat = kwargs.pop('timetickformat', None)
        if not axistype is None:
            self.set_xaxis_type(axistype, timetickformat)
            self._axes.setAutoExtent()

        location = kwargs.pop('location', 'both')
        if location == 'top':
            locs = [Location.TOP]
        elif location == 'bottom':
            locs = [Location.BOTTOM]
        else:
            locs = [Location.BOTTOM, Location.TOP]
        axislist = []
        if self.axestype == '3d':
            axislist.append(self._axes.getXAxis())
        else:
            for loc in locs:
                axislist.append(self._axes.getAxis(loc))

        ticklabelcolor = kwargs.pop('ticklabelcolor', None)
        if not ticklabelcolor is None:
            ticklabelcolor = plotutil.getcolor(ticklabelcolor)
        tick_font = axislist[0].getTickLabelFont()
        tickfontname = kwargs.pop('tickfontname', tick_font.getFontName())
        tickfontsize = kwargs.pop('tickfontsize', tick_font.getSize())
        tickbold = kwargs.pop('tickbold', tick_font.isBold())
        if tickbold:
            font = Font(tickfontname, Font.BOLD, tickfontsize)
        else:
            font = Font(tickfontname, Font.PLAIN, tickfontsize)
        tickavoidcoll = kwargs.pop('tickavoidcoll', None)

        for axis in axislist:
            if not visible is None:
                axis.setVisible(visible)
            if not position is None:
                axis.setPositionType(position[0])
                axis.setPosition(position[1])
            else:
                if not shift is None:
                    axis.setPositionType('OUTERWARD')
                    axis.setPosition(shift)
            if not color is None:
                axis.setColor_All(color)
            if not tickcolor is None:
                axis.setTickColor(tickcolor)
            if not linewidth is None:
                axis.setLineWidth(linewidth)
            if not linestyle is None:
                axis.setLineStyle(linestyle)
            if not tickline is None:
                axis.setDrawTickLine(tickline)
            if not tickwidth is None:
                axis.setTickWidth(tickwidth)
            if not ticklength is None:
                axis.setTickLength(ticklength)
            if not ticklabel is None:
                axis.setDrawTickLabel(ticklabel)
            if not minortick is None:
                axis.setMinorTickVisible(minortick)
            if not minorticknum is None:
                axis.setMinorTickNum(minorticknum)
            if not tickin is None:
                axis.setInsideTick(tickin)
            if not ticklabelcolor is None:
                axis.setTickLabelColor(ticklabelcolor)
            if not tickavoidcoll is None:
                axis.setTickLabelAvoidCollision(tickavoidcoll)
            axis.setTickLabelFont(font)
        
    def yaxis(self, **kwargs):
        """
        Set y-axis of the axes.

        :param color: (*Color*) Color of the y axis. Default is 'black'.
        :param position: (*tuple*) Axis position specified by a 2 tuple of (position type, amount). 
            The position types are ['outerward' | 'axes' | 'data'].
        :param shift: (*int) Y axis shift along x direction. Units are pixel. Default is 0.
        :param visible: (*bool*) Set axis visible or not, Default is `None`.
        :param linewidth: (*float*) Line width of the axis.
        :param linestyle: (*string*) Line style of the axis.
        :param tickline: (*bool*) Draw tick line or not.
        :param tickwidth: (*float*) Tick line width.
        :param ticklength: (*float*) Tick line length.
        :param ticklabel: (*bool*) Draw tick label or not.
        :param minortick: (*bool*) Draw minor tick line or not.
        :param minorticknum: (*int*) Minor tick line number between two adjacent major tick lines.
        :param tickin: (*bool*) Tick lines are ploted inside or outside the axes.
        :param axistype: (*string*) Axis type ['normal' | 'lon' | 'lat' | 'time' | 'log'].
        :param timetickformat: (*string*) Time tick label format, only valid with time axis.
        :param tickfontname: (*string*) Tick label font name.
        :param tickfontsize: (*int*) Tick label font size.
        :param tickbold: (*bool*) Tick label font is bold or not.
        :param tickavoidcoll: (*bool*) Whether avoid collision of tick labels. Default is `True`.
        :param location: (*string*) Locations of the axis ['both' | 'left' | 'right'].
        """
        visible = kwargs.pop('visible', None)
        position = kwargs.pop('position', None)
        if position == 'center':
            position = ['axes', 0.5]
        elif position == 'zero':
            position = ['data', 0]
        shift = kwargs.pop('shift', None)
        color = kwargs.pop('color', None)
        if not color is None:
            color = plotutil.getcolor(color)
        tickcolor = kwargs.pop('tickcolor', None)
        if not tickcolor is None:
            tickcolor = plotutil.getcolor(tickcolor)
        linewidth = kwargs.pop('linewidth', None)
        linestyle = kwargs.pop('linestyle', None)
        tickline = kwargs.pop('tickline', None)
        tickline = kwargs.pop('tickvisible', tickline)
        tickwidth = kwargs.pop('tickwidth', None)
        ticklength = kwargs.pop('ticklength', None)
        ticklabel = kwargs.pop('ticklabel', None)
        minortick = kwargs.pop('minortick', None)
        minorticknum = kwargs.pop('minorticknum', None)
        tickin = kwargs.pop('tickin', None)
        axistype = kwargs.pop('axistype', None)
        timetickformat = kwargs.pop('timetickformat', None)
        if not axistype is None:
            self.set_yaxis_type(axistype, timetickformat)
            self._axes.updateDrawExtent()

        location = kwargs.pop('location', 'both')
        if location == 'left':
            locs = [Location.LEFT]
        elif location == 'right':
            locs = [Location.RIGHT]
        else:
            locs = [Location.LEFT, Location.RIGHT]
        axislist = []
        if self.axestype == '3d':
            axislist.append(self._axes.getYAxis())
        else:
            for loc in locs:
                axislist.append(self._axes.getAxis(loc))

        ticklabelcolor = kwargs.pop('ticklabelcolor', None)
        if not ticklabelcolor is None:
            ticklabelcolor = plotutil.getcolor(ticklabelcolor)
        tick_font = axislist[0].getTickLabelFont()
        tickfontname = kwargs.pop('tickfontname', tick_font.getFontName())
        tickfontsize = kwargs.pop('tickfontsize', tick_font.getSize())
        tickbold = kwargs.pop('tickbold', tick_font.isBold())
        if tickbold:
            font = Font(tickfontname, Font.BOLD, tickfontsize)
        else:
            font = Font(tickfontname, Font.PLAIN, tickfontsize)
        tickavoidcoll = kwargs.pop('tickavoidcoll', None)

        for axis in axislist:
            if not visible is None:
                axis.setVisible(visible)
            if not position is None:
                axis.setPositionType(position[0])
                axis.setPosition(position[1])
            else:
                if not shift is None:
                    axis.setPositionType('OUTERWARD')
                    axis.setPosition(shift)
            if not color is None:
                axis.setColor_All(color)
            if not tickcolor is None:
                axis.setTickColor(tickcolor)
            if not linewidth is None:
                axis.setLineWidth(linewidth)
            if not linestyle is None:
                axis.setLineStyle(linestyle)
            if not tickline is None:
                axis.setDrawTickLine(tickline)
            if not tickwidth is None:
                axis.setTickWidth(tickwidth)
            if not ticklength is None:
                axis.setTickLength(ticklength)
            if not ticklabel is None:
                axis.setDrawTickLabel(ticklabel)
            if not minortick is None:
                axis.setMinorTickVisible(minortick)
            if not minorticknum is None:
                axis.setMinorTickNum(minorticknum)
            if not tickin is None:
                axis.setInsideTick(tickin)
            if not ticklabelcolor is None:
                axis.setTickLabelColor(ticklabelcolor)
            if not tickavoidcoll is None:
                axis.setTickLabelAvoidCollision(tickavoidcoll)
            axis.setTickLabelFont(font)
    
    def xreverse(self):
        """
        Reverse x axis.
        """
        self._axes.getXAxis().setInverse(True)
        
    def yreverse(self):
        """
        Reverse y axis.
        """
        self._axes.getYAxis().setInverse(True)

    def add_patch(self, patch):
        """
        Add a patch.

        :param patch: (*Graphic*) The patch to be added.
        """
        self._axes.addGraphic(patch)
        self._axes.setAutoExtent()
    
    def add_graphic(self, graphic, projection=None, zorder=None):
        """
        Add a graphic
        
        :param graphic: (*Graphic*) The graphic to be added.
        :param projection: (*Projection*) The projection.
        :param zorder: (*int*) Z order of the graphic. Default is `None` that the graphic added
            to the end.
        """
        if not zorder is None:
            if zorder > self.num_graphics():
                zorder = self.num_graphics()

        if projection is None:
            if zorder is None:
                self._axes.addGraphic(graphic)
            else:
                self._axes.addGraphic(zorder, graphic)
        else:
            if zorder is None:
                self._axes.addGraphic(graphic, projection)
            else:
                self._axes.addGraphic(zorder, graphic, projection)

    def get_graphics(self):
        """
        Get graphics
        :return: (*list*) The graphics
        """
        return self._axes.getGraphics()

    def num_graphics(self):
        """
        Get the number of graphics
        :return: (*int*) The number of graphics
        """
        return self._axes.getGraphicNumber()

    def remove_graphic(self, graphic):
        """
        Remove a graphic
        :param graphic: (*int or Graphic*) The graphic
        :return:
        """
        if isinstance(graphic, int):
            if graphic < 0:
                graphic = self._axes.getGraphicNumber() + graphic
        self._axes.getGraphics().remove(graphic)

    def remove(self):
        """
        Remove all graphics.
        """
        self._axes.getGraphics().clear()
        
    def data2pixel(self, x, y, z=None):
        """
        Transform data coordinate to screen coordinate
        
        :param x: (*float*) X coordinate.
        :param y: (*float*) Y coordinate.
        :param z: (*float*) Z coordinate - only used for 3-D axes.
        """
        rect = self._axes.getPositionArea()
        r = self._axes.projToScreen(x, y, rect)
        sx = r[0] + rect.getX()
        sy = r[1] + rect.getY()
        sy = self.figure.get_size()[1] - sy
        return sx, sy
        
    def grid(self, b=None, **kwargs):
        """
        Turn the axes grids on or off.
        
        :param b: If b is *None* and *len(kwargs)==0* , toggle the grid state. If *kwargs*
            are supplied, it is assumed that you want a grid and *b* is thus set to *True* .
        :param which: *which* can be 'major' (default), 'minor', or 'both' to control
            whether major tick grids, minor tick grids, or both are affected.
        :param axis: *axis* can be 'both' (default), 'x', or 'y' to control which set of
            gridlines are drawn.
        :param kwargs: *kwargs* are used to set the grid line properties.
        """
        gridline = self._axes.getGridLine()
        is_draw = gridline.isDrawXLine()
        if b is None:
            is_draw = not gridline.isDrawXLine()
        elif b == True or b == 'on':
            is_draw = True
        elif b == False or b == 'on':
            is_draw = False
        axis = kwargs.pop('axis', 'both')
        if axis == 'both':
            gridline.setDrawXLine(is_draw)
            gridline.setDrawYLine(is_draw)
        elif axis == 'x':
            gridline.setDrawXLine(is_draw)
        elif axis == 'y':
            gridline.setDrawYLine(is_draw)
        color = kwargs.pop('color', None)
        if not color is None:
            c = plotutil.getcolor(color)
            gridline.setColor(c)
        linewidth = kwargs.pop('linewidth', None)
        if not linewidth is None:
            gridline.setSize(linewidth)
        linestyle = kwargs.pop('linestyle', None)
        if not linestyle is None:
            linestyle = plotutil.getlinestyle(linestyle)
            gridline.setStyle(linestyle)
        top = kwargs.pop('top', None)
        if not top is None:
            gridline.setTop(top)
            
    def plot(self, *args, **kwargs):
        """
        Plot lines and/or markers to the axes. *args* is a variable length argument, allowing
        for multiple *x, y* pairs with an optional format string.
        
        :param x: (*array_like*) Input x data.
        :param y: (*array_like*) Input y data.
        :param style: (*string*) Line style for plot.
        
        :returns: Legend breaks of the lines.
        
        The following format string characters are accepted to control the line style or marker:
        
          =========  ===========
          Character  Description
          =========  ===========
          '-'         solid line style
          '--'        dashed line style
          '-.'        dash-dot line style
          ':'         dotted line style
          '.'         point marker
          ','         pixel marker
          'o'         circle marker
          'v'         triangle_down marker
          '^'         triangle_up marker
          '<'         triangle_left marker
          '>'         triangle_right marker
          's'         square marker
          'p'         pentagon marker
          '*'         star marker
          'x'         x marker
          'D'         diamond marker
          =========  ===========
          
        The following color abbreviations are supported:
          
          =========  =====
          Character  Color  
          =========  =====
          'b'        blue
          'g'        green
          'r'        red
          'c'        cyan
          'm'        magenta
          'y'        yellow
          'k'        black
          =========  =====
        """
        xdatalist = []
        ydatalist = []    
        styles = []
        xaxistype = None
        isxylistdata = False
        if len(args) == 1:
            if isinstance(args[0], MIXYListData):
                dataset = args[0].data
                snum = args[0].size()
                isxylistdata = True
            else:
                ydata = np.array(args[0])
                if isinstance(ydata, DimArray):
                    xdata = ydata.dimvalue(0)
                    if ydata.ndim == 2:
                        xdata = ydata.dimvalue(1)
                        xx = np.zeros(ydata.shape)
                        xx[:,:] = xdata
                        xdata = xx
                    # if ydata.islondim(0):
                    #     xaxistype = 'lon'
                    # elif ydata.islatdim(0):
                    #     xaxistype = 'lat'
                    # elif ydata.istimedim(0):
                    #     xaxistype = 'time'
                else:
                    xdata = np.arange(ydata.shape[-1])
                    if ydata.ndim == 2:
                        xx = np.zeros(ydata.shape)
                        xx[:,:] = xdata
                        xdata = xx
                xdatalist.append(xdata)
                ydatalist.append(ydata)
        elif len(args) == 2:
            if isinstance(args[1], basestring):
                ydata = np.array(args[0])
                if isinstance(ydata, DimArray):
                    xdata = ydata.dimvalue(0)
                    if ydata.ndim == 2:
                        xdata = ydata.dimvalue(1)
                        xx = np.zeros(ydata.shape)
                        xx[:,:] = xdata
                        xdata = xx
                    # if ydata.islondim(0):
                    #     xaxistype = 'lon'
                    # elif ydata.islatdim(0):
                    #     xaxistype = 'lat'
                    # elif ydata.istimedim(0):
                    #     xaxistype = 'time'
                else:
                    xdata = np.arange(ydata.shape[-1])
                    if ydata.ndim == 2:
                        xx = np.zeros(ydata.shape)
                        xx[:,:] = xdata
                        xdata = xx
                styles.append(args[1])
            else:
                xdata = args[0]
                ydata = args[1]
            xdatalist.append(xdata)
            ydatalist.append(ydata)
        else:
            c = 'x'
            for arg in args: 
                if c == 'x':   
                    xdatalist.append(arg)
                    c = 'y'
                elif c == 'y':
                    ydatalist.append(arg)
                    c = 's'
                elif c == 's':
                    if isinstance(arg, basestring):
                        styles.append(arg)
                        c = 'x'
                    else:
                        styles.append(None)
                        xdatalist.append(arg)
                        c = 'y'
        if len(styles) == 0:
            styles = None
        else:
            while len(styles) < len(xdatalist):
                styles.append(None)
        
        #Set plot data styles
        zvalues = kwargs.pop('zvalues', None)
        if zvalues is None:
            lines = []
            legend = kwargs.pop('legend', None)
            if not legend is None:
                if isinstance(legend, list):
                    lines = legend
                else:
                    lines = legend.getLegendBreaks()
            else:
                if not styles is None:
                    colors = plotutil.makecolors(len(styles))
                    for i in range(0, len(styles)):
                        label = kwargs.pop('label', 'S_' + str(i + 1))
                        if styles[i] is None:
                            line = plotutil.getlegendbreak('line', **kwargs)[0]
                            line.setCaption(label)
                            line.setColor(colors[i])
                        else:
                            line = plotutil.getplotstyle(styles[i], label, **kwargs)
                        lines.append(line)
                else:
                    snum = len(xdatalist)
                    colors = kwargs.pop('colors', None)
                    if colors is None:
                        if kwargs.has_key('color'):
                            color = kwargs['color']
                            color = plotutil.getcolor(color)
                            colors = [color] * snum
                        else:
                            colors = plotutil.makecolors(snum)
                    else:
                        snum = len(colors) if len(colors) > snum else snum
                    for i in range(0, snum):
                        label = kwargs.pop('label', 'S_' + str(i + 1))
                        line = plotutil.getlegendbreak('line', **kwargs)[0]
                        line.setCaption(label)
                        if i < len(colors):
                            line.setColor(plotutil.getcolor(colors[i]))
                        lines.append(line) 
        else:
            ls = kwargs.pop('symbolspec', None)
            if ls is None:        
                if isinstance(zvalues, (list, tuple)):
                    zvalues = np.array(zvalues)
                levels = kwargs.pop('levs', None)
                if levels is None:
                    levels = kwargs.pop('levels', None)
                if levels is None:
                    cnum = kwargs.pop('cnum', None)
                    if cnum is None:
                        ls = plotutil.getlegendscheme([], zvalues.min(), zvalues.max(), **kwargs)
                    else:
                        ls = plotutil.getlegendscheme([cnum], zvalues.min(), zvalues.max(), **kwargs)
                else:
                    ls = plotutil.getlegendscheme([levels], zvalues.min(), zvalues.max(), **kwargs)
                ls = plotutil.setlegendscheme_line(ls, **kwargs)
        
        if not xaxistype is None:
            self.set_xaxis_type(xaxistype)    
        timetickformat = kwargs.pop('timetickformat', None)
        if not timetickformat is None:
            if not xaxistype == 'time':
                self._axes.setXAxis(TimeAxis('Time', True))
            self._axes.getAxis(Location.BOTTOM).setTimeFormat(timetickformat)
            self._axes.getAxis(Location.TOP).setTimeFormat(timetickformat)

        #Add graphics
        zorder = kwargs.pop('zorder', None)
        iscurve = kwargs.pop('iscurve', False)
        graphics = []
        if isxylistdata:
            graphic = GraphicFactory.createLineString(dataset, lines)
            self.add_graphic(graphic, zorder=zorder)
            graphics.append(graphic)
        else:
            if zvalues is None:
                #Add data series
                snum = len(xdatalist)
                if snum == 1:
                    xdata = plotutil.getplotdata(xdatalist[0])
                    ydata = plotutil.getplotdata(ydatalist[0])
                    if len(lines) == 1:
                        colors = kwargs.pop('colors', None)
                        if not colors is None:
                            colors = plotutil.getcolors(colors)
                            cb = lines[0]
                            lines = []
                            for cc in colors:
                                ncb = cb.clone()
                                ncb.setColor(cc)
                                lines.append(ncb)
                            graphic = GraphicFactory.createLineString(xdata, ydata, lines, iscurve)
                        else:
                            graphic = GraphicFactory.createLineString(xdata, ydata, lines[0], iscurve)
                    else:    #>1                        
                        graphic = GraphicFactory.createLineString(xdata, ydata, lines, iscurve)
                    self.add_graphic(graphic, zorder=zorder)
                    graphics.append(graphic)
                else:
                    for i in range(0, snum):
                        label = kwargs.pop('label', 'S_' + str(i + 1))
                        xdata = plotutil.getplotdata(xdatalist[i])
                        ydata = plotutil.getplotdata(ydatalist[i])
                        graphic = GraphicFactory.createLineString(xdata, ydata, lines[i], iscurve)
                        self.add_graphic(graphic)
                        graphics.append(graphic)
            else:
                xdata = plotutil.getplotdata(xdatalist[0])
                ydata = plotutil.getplotdata(ydatalist[0])
                zdata = plotutil.getplotdata(zvalues)
                graphic = GraphicFactory.createLineString(xdata, ydata, zdata, ls, iscurve)
                self.add_graphic(graphic, zorder=zorder)
                graphics.append(graphic)
        self._axes.setAutoExtent()

        if len(graphics) > 1:
            return graphics
        else:
            return graphics[0]
            
    def step(self, x, y, *args, **kwargs):
        """
        Make a step plot.
        
        :param x: (*array_like*) Input x data.
        :param y: (*array_like*) Input y data.
        :param style: (*string*) Line style for plot.
        :param label: (*string*) Step line label.
        :param where: (*string*) ['pre' | 'post' | 'mid']. If 'pre' (the default), the interval 
            from x[i] to x[i+1] has level y[i+1]. If 'post', that interval has level y[i].
            If ‘mid’, the jumps in y occur half-way between the x-values.
        
        :returns: Step lines
        """
        label = kwargs.pop('label', 'S_0')
        xdata = plotutil.getplotdata(x)
        ydata = plotutil.getplotdata(y)
        if len(args) > 0:
            fmt = args[0]
            fmt = plotutil.getplotstyle(fmt, label, **kwargs)
        else:
            fmt = plotutil.getlegendbreak('line', **kwargs)[0]
            fmt.setCaption(label)        
        where = kwargs.pop('where', 'pre')
        
        #Create graphics
        graphics = GraphicFactory.createStepLineString(xdata, ydata, fmt, where)
        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()
        return graphics 
            
    def scatter(self, *args, **kwargs):
        """
        Make a scatter plot of x vs y, where x and y are sequence like objects of the same lengths.
        
        :param x: (*array_like*) Input x data.
        :param y: (*array_like*) Input y data.
        :param s: (*int*) Size of points.
        :param c: (*Color or array*) Color of the points. Or z values.
        :param alpha: (*int*) The alpha blending value, between 0 (transparent) and 1 (opaque).
        :param marker: (*string*) Marker of the points.
        :param label: (*string*) Label of the points series.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level 
            points to draw, in increasing order.
        
        :returns: Points legend break.
        """
        n = len(args)
        if n == 1:
            a = args[0]
            y = a.dimvalue(0)
            x = a.dimvalue(1)
        else:
            x = args[0]
            y = args[1]

        s = kwargs.pop('s', 8)
        c = kwargs.pop('c', None)

        #Add data series
        label = kwargs.pop('label', 'S_0')
        xdata = plotutil.getplotdata(x)
        ydata = plotutil.getplotdata(y)
        
        #Set plot data styles
        pb, isunique = plotutil.getlegendbreak('point', **kwargs)
        if c is None:
            c = pb.getColor()
            if c is None:
                c = 'b'
        pb.setCaption(label)
        #pstyle = plotutil.getpointstyle(marker)    
        #pb.setStyle(pstyle)
        isvalue = False

        if isinstance(c, NDArray):
            isvalue = True
        elif isinstance(c, (list, tuple)):
            if len(x) == len(c) and isinstance(c[0], (int, long, float)):
                isvalue = True            
        if isvalue:
            ls = kwargs.pop('symbolspec', None)
            if ls is None:        
                if isinstance(c, (list, tuple)):
                    c = np.array(c)
                levels = kwargs.pop('levs', None)
                if levels is None:
                    levels = kwargs.pop('levels', None)
                if levels is None:
                    cnum = kwargs.pop('cnum', None)
                    if cnum is None:
                        ls = plotutil.getlegendscheme([], c.min(), c.max(), **kwargs)
                    else:
                        ls = plotutil.getlegendscheme([cnum], c.min(), c.max(), **kwargs)
                else:
                    ls = plotutil.getlegendscheme([levels], c.min(), c.max(), **kwargs)
                ls = plotutil.setlegendscheme_point(ls, **kwargs)
                if isinstance(s, int):
                    for lb in ls.getLegendBreaks():
                        lb.setSize(s)
                else:
                    n = len(s)
                    for i in range(0, n):
                        ls.getLegendBreaks()[i].setSize(s[i])
            #Create graphics
            graphics = GraphicFactory.createPoints(xdata, ydata, c.asarray(), ls)
        else:
            alpha = kwargs.pop('alpha', None)
            colors = plotutil.getcolors(c, alpha)
            edgecolors = kwargs.pop('edgecolors', pb.getOutlineColor())
            if edgecolors is None:
                edgecolors = [Color.black]
            pbs = []
            if isinstance(s, int):
                s = [s]
            n = max(len(s), len(colors))
            if isinstance(edgecolors, Color):
                edgecolors = [edgecolors]
            if n == 1:
                n = len(edgecolors)
            if n == 1:
                pb.setSize(s[0])
                pb.setColor(colors[0])
                pb.setOutlineColor(edgecolors[0])
                pbs.append(pb)
            else:
                if len(s) == 1:
                    s = s * n
                if len(colors) == 1:
                    colors = colors * n
                if len(edgecolors) == 1:
                    edgecolors = edgecolors * n
                for i in range(n):
                    kwargs['size'] = s[i]
                    kwargs['color'] = colors[i]
                    kwargs['edgecolor'] = edgecolors[i]
                    npb = pb.clone()
                    plotutil.setpointlegendbreak(npb, **kwargs)
                    pbs.append(npb)
            #Create graphics
            graphics = GraphicFactory.createPoints(xdata, ydata, pbs)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()

        return graphics
        
    def semilogy(self, *args, **kwargs):
        """
        Make a plot with log scaling on the y axis.
        
        :param x: (*array_like*) Input x data.
        :param y: (*array_like*) Input y data.
        :param style: (*string*) Line style for plot.
        
        :returns: Legend breaks of the lines.
        
        The following format string characters are accepted to control the line style or marker:
        
          =========  ===========
          Character  Description
          =========  ===========
          '-'         solid line style
          '--'        dashed line style
          '-.'        dash-dot line style
          ':'         dotted line style
          '.'         point marker
          ','         pixel marker
          'o'         circle marker
          'v'         triangle_down marker
          '^'         triangle_up marker
          '<'         triangle_left marker
          '>'         triangle_right marker
          's'         square marker
          'p'         pentagon marker
          '*'         star marker
          'x'         x marker
          'D'         diamond marker
          =========  ===========
          
        The following color abbreviations are supported:
          
          =========  =====
          Character  Color  
          =========  =====
          'b'        blue
          'g'        green
          'r'        red
          'c'        cyan
          'm'        magenta
          'y'        yellow
          'k'        black
          =========  =====
        """       
        lines = self.plot(*args, **kwargs)
        self.set_yaxis_type('log')
        self._axes.setAutoExtent()
        return lines
        
    def semilogx(self, *args, **kwargs):
        """
        Make a plot with log scaling on the x axis.
        
        :param x: (*array_like*) Input x data.
        :param y: (*array_like*) Input y data.
        :param style: (*string*) Line style for plot.
        
        :returns: Legend breaks of the lines.
        
        The following format string characters are accepted to control the line style or marker:
        
          =========  ===========
          Character  Description
          =========  ===========
          '-'         solid line style
          '--'        dashed line style
          '-.'        dash-dot line style
          ':'         dotted line style
          '.'         point marker
          ','         pixel marker
          'o'         circle marker
          'v'         triangle_down marker
          '^'         triangle_up marker
          '<'         triangle_left marker
          '>'         triangle_right marker
          's'         square marker
          'p'         pentagon marker
          '*'         star marker
          'x'         x marker
          'D'         diamond marker
          =========  ===========
          
        The following color abbreviations are supported:
          
          =========  =====
          Character  Color  
          =========  =====
          'b'        blue
          'g'        green
          'r'        red
          'c'        cyan
          'm'        magenta
          'y'        yellow
          'k'        black
          =========  =====
        """       
        lines = self.plot(*args, **kwargs)
        self.set_xaxis_type('log')
        self._axes.setAutoExtent()
        return lines
        
    def loglog(self, *args, **kwargs):
        """
        Make a plot with log scaling on both x and y axis.
        
        :param x: (*array_like*) Input x data.
        :param y: (*array_like*) Input y data.
        :param style: (*string*) Line style for plot.
        
        :returns: Legend breaks of the lines.
        
        The following format string characters are accepted to control the line style or marker:
        
          =========  ===========
          Character  Description
          =========  ===========
          '-'         solid line style
          '--'        dashed line style
          '-.'        dash-dot line style
          ':'         dotted line style
          '.'         point marker
          ','         pixel marker
          'o'         circle marker
          'v'         triangle_down marker
          '^'         triangle_up marker
          '<'         triangle_left marker
          '>'         triangle_right marker
          's'         square marker
          'p'         pentagon marker
          '*'         star marker
          'x'         x marker
          'D'         diamond marker
          =========  ===========
          
        The following color abbreviations are supported:
          
          =========  =====
          Character  Color  
          =========  =====
          'b'        blue
          'g'        green
          'r'        red
          'c'        cyan
          'm'        magenta
          'y'        yellow
          'k'        black
          =========  =====
        """       
        lines = self.plot(*args, **kwargs)
        self.set_xaxis_type('log')
        self.set_yaxis_type('log')
        self._axes.setAutoExtent()
        return lines
        
    def errorbar(self, x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None,
            **kwargs):
        """
        Plot an errorbar graph.
        
        :param x: (*array_like*) X data.
        :param y: (*array_like*) Y data.
        :param yerr: (*scalar or array_like*) Y error values.
        :param xerr: (*scalar or array_like*) X error values.
        :param fmt: (*string*) Plot format string.
        :param ecolor: (*color*) Error bar color.
        :param elinewidth: (*float*) Error bar line width.
        :param capsize: (*float*) The length of the error bar caps.

        :returns: Error bar lines.
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        xdata = plotutil.getplotdata(x)
        ydata = plotutil.getplotdata(y)
        if not yerr is None:
            if isinstance(yerr, (int, float)):
                ye = []
                for i in range(xdata.getSize()):
                    ye.append(yerr)
                yerrB = np.array(ye)._array
                yerrU = yerrB
            else:
                if isinstance(yerr, (list, tuple)):
                    if isinstance(yerr[0], numbers.Number):
                        yerrB = plotutil.getplotdata(yerr)
                        yerrU = yerrB
                    else:
                        yerrB = plotutil.getplotdata(yerr[0])
                        yerrU = plotutil.getplotdata(yerr[1])
                elif yerr.ndim == 2:
                    yerrB = yerr[0,:].asarray()
                    yerrU = yerr[1,:].asarray()
                else:
                    yerrB = plotutil.getplotdata(yerr)
                    yerrU = yerrB
        else:
            yerrB = None
            yerrU = None
            
        if not xerr is None:
            if isinstance(xerr, (int, float)):
                ye = []
                for i in range(xdata.getSize()):
                    ye.append(xerr)
                xerrL = np.array(ye)._array
                xerrR = xerrL         
            else:
                if isinstance(xerr, (list, tuple)):
                    xerrL = plotutil.getplotdata(xerr[0])
                    xerrR = plotutil.getplotdata(xerr[1])
                elif xerr.ndim == 2:
                    xerrL = xerr[0,:].asarray()
                    xerrR = xerr[1,:].asarray()
                else:
                    xerrL = plotutil.getplotdata(xerr)
                    xerrR = xerrL
        else:
            xerrL = None
            xerrR = None
        
        #Get plot data style
        if fmt == '':
            line = plotutil.getlegendbreak('line', **kwargs)[0]
            line.setCaption(label)
        else:
            line = plotutil.getplotstyle(fmt, label, **kwargs)
        if isinstance(line, PolylineBreak):
            eline = line.clone()
        else:
            eline = PolylineBreak()
        eline.setDrawSymbol(False)
        eline.setStyle(LineStyles.SOLID)
        if not ecolor is None:
            ecolor = plotutil.getcolor(ecolor)
            eline.setColor(ecolor)
        if not elinewidth is None:
            eline.setSize(elinewidth)
        
        #Create graphics
        if capsize is None:
            capsize = 10
        graphics = GraphicFactory.createErrorLineString(xdata, ydata, xerrL, xerrR, yerrB, \
            yerrU, line, eline, capsize)
        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()

        return graphics 
            
    def bar(self, x, height, width=0.8, bottom=None, align='center', data=None, **kwargs):
        """
        Make a bar plot.
        
        The bars are positioned at x with the given alignment. Their dimensions are given by 
        width and height. The vertical baseline is bottom (default 0).
        
        :param x: (*array_like*) The x coordinates of the bars. See also align for the alignment 
            of the bars to the coordinates.
        :param height: (*array_like*) The height of the bars.
        :param width: (*array_like*) Optional, the widths of the bars default: 0.8.
        :param bottom: (*array_like*) Optional, the y coordinates of the bars default: None
        :param color: (*Color*) Optional, the color of the bar faces.
        :param edgecolor: (*Color*) Optional, the color of the bar edge. Default is black color.
            Edge line will not be plotted if ``edgecolor`` is ``None``.
        :param linewidth: (*int*) Optional, width of bar edge.
        :param label: (*string*) Label of the bar series.
        :param hatch: (*string*) Hatch string.
        :param hatchsize: (*int*) Hatch size. Default is None (8).
        :param bgcolor: (*Color*) Background color, only valid with hatch.
        :param barswidth: (*float*) Bars width (0 - 1), only used for automatic bar with plot
            (only one argument without ``width`` argument). Default is 0.8.
        :param ecolor: (*Color*) The line color of the errorbars. Default is black.
        :param elinewidth: (*float*) The line width of the errorbars.
        :param capsize: (*float*) The length of the error bar caps in pixels. Default is 0.
        :param morepoints: (*boolean*) More points in bar rectangle. Default is False.
        
        :returns: Bar legend break.
        
        
        The following format string characters are accepted to control the hatch style:
          =========  ===========
          Character  Description
          =========  ===========
          '-'         horizontal hatch style
          '|'         vertical hatch style
          '\\'        forward_diagonal hatch style
          '/'         backward_diagonal hatch style
          '+'         cross hatch style
          'x'         diagonal_cross hatch style
          '.'         dot hatch style
          =========  ===========
          
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        autowidth = False
        isdate = False
        if isinstance(x, (list, tuple)):
            if isinstance(x[0], datetime.datetime):
                isdate = True
        x = np.asarray(x)
        height = np.asarray(height)
        if isdate and width <= 1:
            width = (x[1] - x[0]) * width
        width = np.asarray(width)
        if align == 'center':
            x = x - width / 2
            
        yerr = kwargs.pop('yerr', None)
        if not yerr is None:
            if not isinstance(yerr, (int, float)):
                yerr = plotutil.getplotdata(yerr)  
        if not bottom is None:
            bottom = plotutil.getplotdata(bottom)
        
        #Set plot data styles
        fcobj = kwargs.pop('color', None)
        if fcobj is None:
            fcobj = kwargs.pop('facecolor', 'b')
        if isinstance(fcobj, (tuple, list)):
            colors = plotutil.getcolors(fcobj)
        else:
            color = plotutil.getcolor(fcobj)
            colors = [color]
        ecobj = kwargs.pop('edgecolor', 'k')
        edgecolor = plotutil.getcolor(ecobj)
        linewidth = kwargs.pop('linewidth', 1.0) 
        hatch = kwargs.pop('hatch', None)
        hatch = plotutil.gethatch(hatch) 
        hatchsize = kwargs.pop('hatchsize', None)
        bgcolor = kwargs.pop('bgcolor', None)
        bgcolor = plotutil.getcolor(bgcolor)
        ecolor = kwargs.pop('ecolor', 'k')
        ecolor = plotutil.getcolor(ecolor)
        elinewidth = kwargs.pop('elinewidth', None)
        capsize = kwargs.pop('capsize', None)
        morepoints = kwargs.pop('morepoints', False)
        barbreaks = []
        for color in colors:
            lb = BarBreak()
            lb.setCaption(label)
            lb.setColor(color)    
            if edgecolor is None:
                lb.setDrawOutline(False)
            else:
                lb.setOutlineColor(edgecolor)  
            lb.setOutlineSize(linewidth)   
            if not hatch is None:
                lb.setStyle(hatch)
                if not bgcolor is None:
                    lb.setBackColor(bgcolor)
                if not hatchsize is None:
                    lb.setStyleSize(hatchsize)
            lb.setErrorColor(ecolor)
            if not elinewidth is None:
                lb.setErrorSize(elinewidth)
            if not capsize is None:
                lb.setCapSize(capsize)
            barbreaks.append(lb)
            
        #Create bar graphics
        if isinstance(width, NDArray):
            width = width.asarray()
        if morepoints:
            graphics = GraphicFactory.createBars1(x.asarray(), height.asarray(), autowidth, width, not yerr is None, yerr, \
                not bottom is None, bottom, barbreaks)
        else:
            graphics = GraphicFactory.createBars(x.asarray(), height.asarray(), autowidth, width, not yerr is None, yerr, \
                not bottom is None, bottom, barbreaks)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()
        if autowidth:
            barswidth = kwargs.pop('barswidth', 0.8)
            self._axes.setBarsWidth(barswidth)

        return barbreaks
 
    def barh(self, *args, **kwargs):
        """
        Make a horizontal bar plot.
        
        Make a bar plot with rectangles bounded by:
            left, left + width, y, y + height
        
        :param y: (*array_like*) The y coordinates of the bars.
        :param width: (*array_like*) The widths of the bars.
        :param height: (*array_like*) Optional, the height of the bars default: 0.8.
        :param left: (*array_like*) Optional, the x coordinates of the bars default: None
        :param color: (*Color*) Optional, the color of the bar faces.
        :param edgecolor: (*Color*) Optional, the color of the bar edge. Default is black color.
            Edge line will not be plotted if ``edgecolor`` is ``None``.
        :param linewidth: (*int*) Optional, width of bar edge.
        :param label: (*string*) Label of the bar series.
        :param hatch: (*string*) Hatch string.
        :param hatchsize: (*int*) Hatch size. Default is None (8).
        :param bgcolor: (*Color*) Background color, only valid with hatch.
        :param barswidth: (*float*) Bars width (0 - 1), only used for automatic bar with plot
            (only one argument widthout ``width`` augument). Defaul is 0.8.
        :param morepoints: (*boolean*) More points in bar rectangle. Defaul is False.
        
        :returns: Bar legend break.
        
        
        The following format string characters are accepted to control the hatch style:
          =========  ===========
          Character  Description
          =========  ===========
          '-'         horizontal hatch style
          '|'         vertical hatch style
          '\\'        forward_diagonal hatch style
          '/'         backward_diagonal hatch style
          '+'         cross hatch style
          'x'         diagonal_cross hatch style
          '.'         dot hatch style
          =========  ===========
          
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        xdata = None
        autoheight = True
        height = 0.8
        if len(args) == 1:
            xdata = args[0]
        elif len(args) == 2:
            if isinstance(args[1], (int, float)):
                xdata = args[0]
                height = args[1]
                autoheight = False
            else:
                ydata = args[0]
                xdata = args[1]
        else:
            ydata = args[0]
            xdata = args[1]
            height = args[2]
            autoheight = False        
        
        if ydata is None:
            ydata = []
            for i in range(1, len(args[0]) + 1):
                ydata.append(i)
        ydata = plotutil.getplotdata(ydata)
        xdata = plotutil.getplotdata(xdata)
        height = plotutil.getplotdata(height)
        xerr = kwargs.pop('xerr', None)
        if not xerr is None:
            if not isinstance(xerr, (int, float)):
                xerr = plotutil.getplotdata(xerr)
        left = kwargs.pop('left', None)   
        if not left is None:
            left = plotutil.getplotdata(left)
        
        #Set plot data styles
        fcobj = kwargs.pop('color', None)
        if fcobj is None:
            fcobj = kwargs.pop('facecolor', 'b')
        if isinstance(fcobj, (tuple, list)):
            colors = plotutil.getcolors(fcobj)
        else:
            color = plotutil.getcolor(fcobj)
            colors = [color]
        ecobj = kwargs.pop('edgecolor', 'k')
        edgecolor = plotutil.getcolor(ecobj)
        linewidth = kwargs.pop('linewidth', 1.0) 
        hatch = kwargs.pop('hatch', None)
        hatch = plotutil.gethatch(hatch) 
        hatchsize = kwargs.pop('hatchsize', None)
        bgcolor = kwargs.pop('bgcolor', None)
        bgcolor = plotutil.getcolor(bgcolor)
        ecolor = kwargs.pop('ecolor', 'k')
        ecolor = plotutil.getcolor(ecolor)
        barbreaks = []
        for color in colors:
            lb = BarBreak()
            lb.setCaption(label)
            lb.setColor(color)    
            if edgecolor is None:
                lb.setDrawOutline(False)
            else:
                lb.setOutlineColor(edgecolor)  
            lb.setOutlineSize(linewidth)   
            if not hatch is None:
                lb.setStyle(hatch)
                if not bgcolor is None:
                    lb.setBackColor(bgcolor)
                if not hatchsize is None:
                    lb.setStyleSize(hatchsize)
            lb.setErrorColor(ecolor)
            barbreaks.append(lb)
            
        #Create bar graphics
        graphics = GraphicFactory.createHBars(ydata, xdata, autoheight, height, not xerr is None, xerr, \
            not left is None, left, barbreaks)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()
        if autoheight:
            barsheight = kwargs.pop('barsheight', 0.8)
            self._axes.setBarsWidth(barsheight)

        return barbreaks
        
    def hist(self, x, bins=10, range=None, density=False, cumulative=False,
            bottom=None, histtype='bar', align='mid',
            orientation='vertical', rwidth=None, log=False, **kwargs):
        """
        Plot a histogram.
        
        :param x: (*array_like*) Input values, this takes either a single array or a sequency of arrays 
            which are not required to be of the same length.
        :param bins: (*int*) If an integer is given, bins + 1 bin edges are returned.
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        
        #histogram
        m, bins = np.histogram(x, bins=bins, density=density)
        width = np.diff(bins)
        if cumulative:
            m = np.cumsum(m * width)
        if not rwidth is None:
            width = width * rwidth
        barbreaks = self.bar(bins[:-1], m, width, align='center', **kwargs)

        return m, bins, barbreaks
        
    def hist_back(self, x, bins=10, range=None, density=False, cumulative=False,
            bottom=None, histtype='bar', align='mid',
            orientation='vertical', rwidth=None, log=False, **kwargs):
        """
        Plot a histogram.
        
        :param x: (*array_like*) Input values, this takes either a single array or a sequency of arrays 
            which are not required to be of the same length.
        :param bins: (*int*) If an integer is given, bins + 1 bin edges are returned.
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        
        #Set plot data styles
        fcobj = kwargs.pop('color', None)
        if fcobj is None:
            fcobj = kwargs.pop('facecolor', 'b')
        if isinstance(fcobj, (tuple, list)):
            colors = plotutil.getcolors(fcobj)
        else:
            color = plotutil.getcolor(fcobj)
            colors = [color]
        ecobj = kwargs.pop('edgecolor', 'k')
        edgecolor = plotutil.getcolor(ecobj)
        linewidth = kwargs.pop('linewidth', 1.0) 
        hatch = kwargs.pop('hatch', None)
        hatch = plotutil.gethatch(hatch) 
        hatchsize = kwargs.pop('hatchsize', None)
        bgcolor = kwargs.pop('bgcolor', None)
        bgcolor = plotutil.getcolor(bgcolor)
        ecolor = kwargs.pop('ecolor', 'k')
        ecolor = plotutil.getcolor(ecolor)
        barbreaks = []
        for color in colors:
            lb = BarBreak()
            lb.setCaption(label)
            lb.setColor(color)    
            if edgecolor is None:
                lb.setDrawOutline(False)
            else:
                lb.setOutlineColor(edgecolor)  
            lb.setOutlineSize(linewidth)   
            if not hatch is None:
                lb.setStyle(hatch)
                if not bgcolor is None:
                    lb.setBackColor(bgcolor)
                if not hatchsize is None:
                    lb.setStyleSize(hatchsize)
            lb.setErrorColor(ecolor)
            barbreaks.append(lb)
            
        #Create bar graphics
        x = plotutil.getplotdata(x)
        if not isinstance(bins, numbers.Number):
            bins = plotutil.getplotdata(bins)
        graphics = GraphicFactory.createHistBars(x, bins, barbreaks)        
        self.add_graphic(graphics)
        self._axes.setAutoExtent()

        return lb
        
    def stem(self, *args, **kwargs):
        """
        Make a stem plot.
        
        A stem plot plots vertical lines at each x location from the baseline to y, and 
        places a marker there.
        
        :param x: (*array_like*) The x-positions of the stems.
        :param y: (*array_like*) The y-values of the stem heads.
        :param bottom: (*array_like*) Optional, The y-position of the baseline.
        :param linefmt: (*dict*) Optional, stem line format.
        :param markerfmt: (*dict*) Optional, stem marker format.
        :param color: (*Color*) Optional, the color of the stem.
        
        :returns: Stem line legend break.                  
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        xdata = None
        if len(args) == 1:
            ydata = args[0]
        else:
            xdata = args[0]
            ydata = args[1]       
        
        if xdata is None:
            xdata = []
            for i in range(1, len(args[0]) + 1):
                xdata.append(i)
        xdata = plotutil.getplotdata(xdata)
        ydata = plotutil.getplotdata(ydata)        
        bottom = kwargs.pop('bottom', 0)   
        
        #Set plot data styles
        color = kwargs.pop('color', None)
        if not color is None:
            color = plotutil.getcolor(color)
        linefmt = kwargs.pop('linefmt', None)
        if linefmt is None:
            linefmt = PolylineBreak()
            linefmt.setColor(color is None and Color.red or color)
        else:
            linefmt = plotutil.getlegendbreak('line', **linefmt)[0]
        linefmt.setCaption(label)
        markerfmt = kwargs.pop('markerfmt', None)
        if markerfmt is None:
            markerfmt = PointBreak()
            markerfmt.setOutlineColor(color is None and Color.red or color)
            markerfmt.setDrawFill(False)
        else:
            markerfmt = plotutil.getlegendbreak('point', **markerfmt)[0]
        basefmt = kwargs.pop('basefmt', None)
        if basefmt is None:
            basefmt = PolylineBreak()
            basefmt.setColor(color is None and Color.red or color)
        else:
            basefmt = plotutil.getlegendbreak('line', **basefmt)[0]
        
        #Create stem graphics
        graphics = GraphicFactory.createStems(xdata, ydata, linefmt, markerfmt, \
            basefmt, bottom)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()

        return linefmt
        
    def contour(self, *args, **kwargs):
        """
        Plot contours.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param z: (*array_like*) 2-D z value array.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves 
            to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a 
            string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib 
            color args (string, float, rgb, etc), different levels will be plotted in different colors in 
            the order specified.
        :param smooth: (*boolean*) Smooth countour lines or not.
        
        :returns: (*VectoryLayer*) Contour VectoryLayer created from array data.
        """
        n = len(args)
        ls = kwargs.pop('symbolspec', None)
        cmap = plotutil.getcolormap(**kwargs)
        fill_value = kwargs.pop('fill_value', -9999.0)
        xaxistype = None
        if n <= 2:
            a = args[0]
            if isinstance(a, DimArray):
                y = a.dimvalue(0)
                x = a.dimvalue(1)
            else:
                x = np.arange(a.shape[1])
                y = np.arange(a.shape[0])
            args = args[1:]
        elif n <=4:
            x = args[0]
            y = args[1]
            a = args[2]
            args = args[3:]

        vmin = kwargs.pop('vmin', a.min())
        vmax = kwargs.pop('vmax', a.max())
        if ls is None:
            if len(args) > 0:
                level_arg = args[0]
                if isinstance(level_arg, int):
                    cn = level_arg
                    ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap)
                else:
                    if isinstance(level_arg, NDArray):
                        level_arg = level_arg.aslist()
                    ls = LegendManage.createLegendScheme(vmin, vmax, level_arg, cmap)
            else:    
                ls = LegendManage.createLegendScheme(vmin, vmax, cmap)
            ls = ls.convertTo(ShapeTypes.POLYLINE)
            plotutil.setlegendscheme(ls, **kwargs)

        # norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
        # ls.setNormalize(norm._norm)
        # ls.setColorMap(cmap)
        smooth = kwargs.pop('smooth', True)
        if x.ndim == 2 and y.ndim == 2:
            griddata_props = kwargs.pop('griddata_props', dict(method='idw', pointnum=5, convexhull=True))
            a, x, y = np.griddata((x,y), a, **griddata_props)
        igraphic = GraphicFactory.createContourLines(x.asarray(), y.asarray(), a.asarray(), ls, smooth)

        if not xaxistype is None:
            self.set_xaxis_type(xaxistype)
            self._axes.updateDrawExtent()

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(igraphic, zorder=zorder)
        #self._axes.setAutoExtent()
        self._axes.setExtent(igraphic.getExtent())
        self._axes.setDrawExtent(igraphic.getExtent())

        return igraphic
        
    def clabel(self, layer, **kwargs):
        """
        Add contour layer labels.
        
        :param layer: (*MILayer*) The contour layer.
        :param fontname, fontsize: The font auguments.
        :param color: (*color*) The label color. Default is ``None``, the label color will be set as
            same as color of the line.
        :param dynamic: (*boolean*) Draw labels dynamic or not. Default is ``True``.
        :param drawshadow: (*boolean*) Draw shadow under labels or not.
        :param fieldname: (*string*) The field name used for label.
        :param xoffset: (*int*) X offset of the labels.
        :param yoffset: (int*) Y offset of the labels.
        :param avoidcoll: (*boolean*) Avoid labels collision or not.
        """
        color = kwargs.pop('color', None)    
        gc = layer
        if isinstance(layer, MILayer):
            gc = layer._layer
        dynamic = kwargs.pop('dynamic', True)
        if gc.getShapeType() != ShapeTypes.POLYLINE:
            dynamic = False
        drawshadow = kwargs.pop('drawshadow', dynamic)    
        labelset = gc.getLabelSet()
        if isinstance(gc, MapLayer):
            fieldname = kwargs.pop('fieldname', labelset.getFieldName())
            if fieldname is None:
                fieldname = gc.getFieldName(0)
            labelset.setFieldName(fieldname)
        fontdic = kwargs.pop('font', None)
        if not fontdic is None:
            font = plotutil.getfont(fontdic)
            labelset.setLabelFont(font)
        else:
            font = plotutil.getfont_1(**kwargs)
            labelset.setLabelFont(font)
        if color is None:
            labelset.setColorByLegend(True)
        else:
            labelset.setColorByLegend(False)
            color = plotutil.getcolor(color)
            labelset.setLabelColor(color)
        labelset.setDrawShadow(drawshadow)
        xoffset = kwargs.pop('xoffset', 0)
        labelset.setXOffset(xoffset)
        yoffset = kwargs.pop('yoffset', 0)
        labelset.setYOffset(yoffset)
        avoidcoll = kwargs.pop('avoidcoll', True)
        labelset.setAvoidCollision(avoidcoll)
        decimals = kwargs.pop('decimals', None)
        if not decimals is None:
            labelset.setAutoDecimal(False)
            labelset.setDecimalDigits(decimals)
        if dynamic:
            gc.addLabelsContourDynamic(gc.getExtent())
        else:
            gc.addLabels()
        
    def contourf(self, *args, **kwargs):
        """
        Plot filled contours.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param z: (*array_like*) 2-D z value array.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves 
            to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a 
            string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib 
            color args (string, float, rgb, etc), different levels will be plotted in different colors in 
            the order specified.
        :param smooth: (*boolean*) Smooth countour lines or not.
        
        :returns: (*VectoryLayer*) Contour filled VectoryLayer created from array data.
        """
        n = len(args)    
        ls = kwargs.pop('symbolspec', None)
        cmap = plotutil.getcolormap(**kwargs)
        fill_value = kwargs.pop('fill_value', -9999.0)
        xaxistype = None
        if n <= 2:
            a = args[0]
            if isinstance(a, DimArray):
                y = a.dimvalue(0)
                x = a.dimvalue(1)
            else:
                x = np.arange(a.shape[1])
                y = np.arange(a.shape[0])
            args = args[1:]
        elif n <=4:
            x = args[0]
            y = args[1]
            a = args[2]
            args = args[3:]

        vmin = kwargs.pop('vmin', a.min())
        vmax = kwargs.pop('vmax', a.max())
        if ls is None:
            if len(args) > 0:
                level_arg = args[0]
                if isinstance(level_arg, int):
                    cn = level_arg
                    ls = LegendManage.createLegendScheme(vmin, vmax, cn, cmap)
                else:
                    if isinstance(level_arg, NDArray):
                        level_arg = level_arg.aslist()
                    ls = LegendManage.createLegendScheme(vmin, vmax, level_arg, cmap)
            else:    
                ls = LegendManage.createLegendScheme(vmin, vmax, cmap)
        ls = ls.convertTo(ShapeTypes.POLYGON)
        if not kwargs.has_key('edgecolor'):
            kwargs['edgecolor'] = None
        plotutil.setlegendscheme(ls, **kwargs)
        # norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
        # ls.setNormalize(norm._norm)
        # ls.setColorMap(cmap)
        smooth = kwargs.pop('smooth', True)
        if x.ndim == 2 and y.ndim == 2:
            griddata_props = kwargs.pop('griddata_props', dict(method='idw', pointnum=5, convexhull=True))
            a, x, y = np.griddata((x,y), a, **griddata_props)
        igraphic = GraphicFactory.createContourPolygons(x.asarray(), y.asarray(), a.asarray(), ls, smooth)
        
        visible = kwargs.pop('visible', True)
        if visible:
            if not xaxistype is None:
                self.set_xaxis_type(xaxistype)
                self._axes.updateDrawExtent()

            zorder = kwargs.pop('zorder', None)
            self.add_graphic(igraphic, zorder=zorder)
            #self.setAutoExtent()
            self._axes.setExtent(igraphic.getExtent())
            self._axes.setDrawExtent(igraphic.getExtent())
   
        return igraphic

    def imshow(self, *args, **kwargs):
        """
        Display an image on the axes.
        
        :param X: (*array_like*) 2-D or 3-D (RGB or RGBA) image value array or BufferedImage.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves 
            to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a 
            string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib 
            color args (string, float, rgb, etc), different levels will be plotted in different colors in 
            the order specified.
        :param interpolation: (*string*) Interpolation option [None | bilinear | bicubic].
        
        :returns: (*Image graphic*) Image graphic created from array data.
        """
        n = len(args)
        cmap = plotutil.getcolormap(**kwargs)
        fill_value = kwargs.pop('fill_value', -9999.0)
        xaxistype = None
        isrgb = False
        isimage = False
        extent = None
        if n >= 3:
            xdata = args[0]
            ydata = args[1]
            extent = [xdata[0],xdata[-1],ydata[0],ydata[-1]]
            args = args[2:]
        X = args[0]
        if isinstance(X, (list, tuple)):
            isrgb = True
        elif isinstance(X, BufferedImage):
            isimage = True
        elif X.ndim > 2:
            isrgb = True
        else:
            if n >= 3:
                gdata = np.asgridarray(X, xdata, ydata)
            else:
                gdata = np.asgridarray(X)
        args = args[1:]   
        
        extent = kwargs.pop('extent', extent)
        if isrgb:
            if isinstance(X, (list, tuple)):
                rgbd = []
                for d in rgbdata:
                    rgbd.append(d.asarray())
                rgbdata = rgbd
            else:
                rgbdata = X.asarray()
            igraphic = GraphicFactory.createImage(rgbdata, extent)
            ls = None
        elif isimage:
            igraphic = GraphicFactory.createImage(X)
            ls = None
        else:
            ls = kwargs.pop('symbolspec', None)
            if ls is None:
                vmin = kwargs.pop('vmin', gdata.min())
                vmax = kwargs.pop('vmax', gdata.max())
                if len(args) > 0:
                    level_arg = args[0]
                    if isinstance(level_arg, int):
                        cn = level_arg
                        ls = LegendManage.createImageLegend(gdata, cn, cmap)
                    else:
                        if isinstance(level_arg, NDArray):
                            level_arg = level_arg.aslist()
                        ls = LegendManage.createImageLegend(gdata, level_arg, cmap)
                else:
                    ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
                    norm = kwargs.pop('norm', colors.Normalize(vmin, vmax))
                    ls.setNormalize(norm._norm)
                    ls.setColorMap(cmap)
                ls = ls.convertTo(ShapeTypes.IMAGE)
                plotutil.setlegendscheme(ls, **kwargs)
            igraphic = GraphicFactory.createImage(gdata, ls, extent)

        interpolation = kwargs.pop('interpolation', None)
        if not interpolation is None:
            igraphic.getShape().setInterpolation(interpolation)

        if not xaxistype is None:
            self.set_xaxis_type(xaxistype)
            self._axes.updateDrawExtent()

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(igraphic, zorder=zorder)
        self._axes.setAutoExtent()
        gridline = self._axes.getGridLine()
        gridline.setTop(True)

        if ls is None:
            return igraphic
        else:
            return ls
        
    def pcolor(self, *args, **kwargs):
        """
        Draw a pseudocolor plot.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param z: (*array_like*) 2-D z value array.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves 
            to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a 
            string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib 
            color args (string, float, rgb, etc), different levels will be plotted in different colors in 
            the order specified.
        
        :returns: (*GraphicCollection*) Polygon graphic collection.
        """
        n = len(args) 
        if n <= 2:
            a = args[0]
            if isinstance(a, DimArray):
                y = a.dimvalue(0)
                x = a.dimvalue(1)
            else:
                ny, nx = a.shape
                y = np.arange(ny)
                x = np.arange(nx)
            args = args[1:]
        else:
            x = args[0]
            y = args[1]
            a = args[2]
            args = args[3:]
        if a.ndim == 2 and x.ndim == 1:            
            x, y = np.meshgrid(x, y)            
        ls = plotutil.getlegendscheme(args, a.min(), a.max(), **kwargs)   
        ls = ls.convertTo(ShapeTypes.POLYGON)
        if not kwargs.has_key('edgecolor'):
            kwargs['edgecolor'] = None
        plotutil.setlegendscheme(ls, **kwargs)
        graphics = GraphicFactory.createPColorPolygons(x.asarray(), y.asarray(), a.asarray(), ls)            
        visible = kwargs.pop('visible', True)
        if visible:
            zorder = kwargs.pop('zorder', None)
            self.add_graphic(graphics, zorder=zorder)
            self._axes.setExtent(graphics.getExtent())
            self._axes.setDrawExtent(graphics.getExtent())
        return graphics
        
    def gridshow(self, *args, **kwargs):
        """
        Draw a grid plot.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param z: (*array_like*) 2-D z value array.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves 
            to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a 
            string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib 
            color args (string, float, rgb, etc), different levels will be plotted in different colors in 
            the order specified.
        :param fill_value: (*float*) Fill_value. Default is ``-9999.0``.
        
        :returns: (*GraphicCollection*) Polygon graphic collection.
        """
        fill_value = kwargs.pop('fill_value', -9999.0)
        n = len(args) 
        if n <= 2:
            a = args[0]
            y = a.dimvalue(0)
            x = a.dimvalue(1)
            args = args[1:]
        else:
            x = args[0]
            y = args[1]
            a = args[2]
            args = args[3:]
            
        ls = plotutil.getlegendscheme(args, a.min(), a.max(), **kwargs)   
        ls = ls.convertTo(ShapeTypes.POLYGON)
        plotutil.setlegendscheme(ls, **kwargs)
        graphics = GraphicFactory.createGridPolygons(x.asarray(), y.asarray(), a.asarray(), ls)            
        visible = kwargs.pop('visible', True)
        if visible:
            zorder = kwargs.pop('zorder', None)
            self.add_graphic(graphics, zorder=zorder)
            self._axes.setExtent(graphics.getExtent())
            self._axes.setDrawExtent(graphics.getExtent())
        return graphics
        
    def text(self, x, y, s, **kwargs):
        """
        Add text to the axes. Add text in string *s* to axis at location *x* , *y* , data
        coordinates.
        
        :param x: (*float*) Data x coordinate.
        :param y: (*float*) Data y coordinate.
        :param s: (*string*) Text.
        :param fontname: (*string*) Font name. Default is ``Arial`` .
        :param fontsize: (*int*) Font size. Default is ``14`` .
        :param bold: (*boolean*) Is bold font or not. Default is ``False`` .
        :param color: (*color*) Tick label string color. Default is ``black`` .
        :param coordinates=['axes'|'figure'|'data'|'inches']: (*string*) Coordinate system and units for 
            *X, Y*. 'axes' and 'figure' are normalized coordinate system with 0,0 in the lower left and 
            1,1 in the upper right, 'data' are the axes data coordinates (Default value); 'inches' is 
            position in the figure in inches, with 0,0 at the lower left corner.
        """
        ctext = plotutil.text(x, y, s, **kwargs)
        self._axes.addText(ctext)
        return ctext
    
    def arrow(self, x, y, dx, dy, **kwargs):
        """
        Add an arrow to the axes.
        
        :param x: (*float*) X coordinate.
        :param y: (*float*) Y coordinate.
        :param dx: (*float*) The length of arrow along x direction. 
        :param dy: (*float*) The length of arrow along y direction.
        
        :returns: Arrow graphic.
        """
        if not kwargs.has_key('facecolor'):
            kwargs['facecolor'] = (51,204,255)
        apb, isunique = plotutil.getlegendbreak('polygon', **kwargs)
        apb = plotutil.polygon2arrow(apb, **kwargs)
        graphic = GraphicFactory.createArrow(x, y, dx, dy, apb)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphic, zorder=zorder)
        self._axes.setAutoExtent()
        
        return graphic
    
    def arrowline(self, x, y, dx=0, dy=0, **kwargs):
        """
        Add an arrow line to the axes.
        
        :param x: (*float or array_like*) X coordinates.
        :param y: (*float or array_like*) Y coordinates.
        :param dx: (*float*) The length of arrow along x direction. Only valid when x is float.
        :param dy: (*float*) The length of arrow along y direction. Only valid when y is float.
        
        :returns: Arrow line graphic.
        """
        if isinstance(x, (list, tuple)):
            x = np.array(x)
        if isinstance(y, (list, tuple)):
            y = np.array(y)
            
        alb, isunique = plotutil.getlegendbreak('line', **kwargs)
        alb = plotutil.line2arrow(alb, **kwargs)
        if isinstance(x, NDArray):
            iscurve = kwargs.pop('iscurve', False)
            graphic = GraphicFactory.createArrowLine(x._array, y._array, alb, iscurve)
        else:
            graphic = GraphicFactory.createArrowLine(x, y, dx, dy, alb)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphic, zorder=zorder)
        self._axes.setAutoExtent()
        
        return graphic
        
    def annotate(self, s, xy, *args, **kwargs):
        """
        Annotate the point xy with text s.
        
        :param s: (*string*) The text of the annotation.
        :param xy: (*float, float*) The point (x,y) to annotate.
        :param xytext: (*float, float*) The position (x,y) to place the text at. If None, 
            defaults to xy.
        :param arrowprops: (*dict*) Arrow properties.
            
        :returns: Annotation.
        """
        if len(args) > 0:
            xytext = args[0]
        else:
            xytext = xy
        
        ctext = plotutil.text(xytext[0], xytext[1], s, **kwargs)
        self._axes.addText(ctext)
                
        arrowprops = kwargs.pop('arrowprops', dict())
        if not arrowprops.has_key('headwidth'):
            arrowprops['headwidth'] = 10
        if not arrowprops.has_key('shrink'):
            arrowprops['shrink'] = 0.05
        alb, isunique = plotutil.getlegendbreak('line', **arrowprops)
        alb = plotutil.line2arrow(alb, **arrowprops)
        x0 = xytext[0]
        y0 = xytext[1]
        dx = xy[0] - xytext[0]
        dy = xy[1] - xytext[1]
        shrink = arrowprops['shrink']
        if shrink > 0:
            sx = dx * shrink
            sy = dy * shrink
            x0 = xytext[0] + sx
            y0 = xytext[1] + sy
            dx = dx - sx * 2
            dy = dy - sy * 2
        graphic = GraphicFactory.createArrowLine(x0, y0, dx, dy, alb)
        self.add_graphic(graphic)
        self._axes.setAutoExtent()
        
        return ctext, graphic

    def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
        """
        Add a horizontal line across the axis.
        Parameters
        ----------
        y : float, default: 0
            y position in data coordinates of the horizontal line.
        xmin : float, default: 0
            Should be between 0 and 1, 0 being the far left of the plot, 1 the
            far right of the plot.
        xmax : float, default: 1
            Should be between 0 and 1, 0 being the far left of the plot, 1 the
            far right of the plot.
        Returns
        -------
        `~matplotlib.lines.Line2D`
        """
        pass
    
    def patch(self, x, y=None, **kwargs):
        """
        Create one or more filled polygons.
        
        :param x: (*array_like*) X coordinates for each vertex. X should be PolygonShape if y
            is None.
        :param y: (*array_like*) Y coordinates for each vertex.
        """
        lbreak, isunique = plotutil.getlegendbreak('polygon', **kwargs)
        if y is None:
            graphics = Graphic(x, lbreak)
        else:
            x = plotutil.getplotdata(x)
            y = plotutil.getplotdata(y)
            graphics = GraphicFactory.createPolygons(x, y, lbreak)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()
        return graphics
        
    def rectangle(self, position, curvature=None, **kwargs):
        """
        Create one or more filled polygons.
        
        :param position: (*list*) Position of the rectangle [x, y, width, height].
        :param curvature: (*list*) Curvature of the rectangle [x, y]. Default is None.
        """
        lbreak, isunique = plotutil.getlegendbreak('polygon', **kwargs)
        if isinstance(curvature, (int, float)):
            curvature = [curvature, curvature]
        graphic = GraphicFactory.createRectangle(position, curvature, lbreak)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphic, zorder=zorder)
        self._axes.setAutoExtent()
        return graphic

    def fill_between(self, x, y1, y2=0, where=None, **kwargs):
        """
        Make filled polygons between two curves (y1 and y2) where ``where==True``.
        
        :param x: (*array_like*) An N-length array of the x data.
        :param y1: (*array_like*) An N-length array (or scalar) of the y data.
        :param y2: (*array_like*) An N-length array (or scalar) of the y data.
        :param where: (*array_like*) If None, default to fill between everywhere. If not None, it is an 
            N-length boolean array and the fill will only happen over the regions where ``where==True``.
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        dn = len(x)
        xdata = plotutil.getplotdata(x)
        if isinstance(y1, (int, long, float)):
            yy = []
            for i in range(dn):
                yy.append(y1)
            y1 = np.array(yy)._array
        else:
            y1 = plotutil.getplotdata(y1)
        if isinstance(y2, (int, long, float)):
            yy = []
            for i in range(dn):
                yy.append(y2)
            y2 = np.array(yy)._array
        else:
            y2 = plotutil.getplotdata(y2)
        if not where is None:
            if isinstance(where, (tuple, list)):
                where = np.array(where)
            where = where.asarray()
        
        #Set plot data styles
        # if not 'fill' in kwargs:
            # kwargs['fill'] = True
        # if not 'edge' in kwargs:
            # kwargs['edge'] = False
        pb, isunique = plotutil.getlegendbreak('polygon', **kwargs)
        pb.setCaption(label)
        
        #Create graphics
        graphics = GraphicFactory.createFillBetweenPolygons(xdata, y1, y2, where, pb)
        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()

        return pb 
        
    def fill_betweenx(self, y, x1, x2=0, where=None, **kwargs):
        """
        Make filled polygons between two curves (x1 and x2) where ``where==True``.
        
        :param y: (*array_like*) An N-length array of the y data.
        :param x1: (*array_like*) An N-length array (or scalar) of the x data.
        :param x2: (*array_like*) An N-length array (or scalar) of the x data.
        :param where: (*array_like*) If None, default to fill between everywhere. If not None, it is an 
            N-length boolean array and the fill will only happen over the regions where ``where==True``.
        """
        #Add data series
        label = kwargs.pop('label', 'S_0')
        dn = len(y)
        ydata = plotutil.getplotdata(y)
        if isinstance(x1, (int, long, float)):
            xx = []
            for i in range(dn):
                xx.append(x1)
            x1 = np.array(xx)._array
        else:
            x1 = plotutil.getplotdata(x1)
        if isinstance(x2, (int, long, float)):
            xx = []
            for i in range(dn):
                xx.append(x2)
            x2 = np.array(xx)._array
        else:
            x2 = plotutil.getplotdata(x2)
        if not where is None:
            if isinstance(where, (tuple, list)):
                where = np.array(where)
            where = where.asarray()
        
        #Set plot data styles
        # if not 'fill' in kwargs:
            # kwargs['fill'] = True
        # if not 'edge' in kwargs:
            # kwargs['edge'] = False
        pb, isunique = plotutil.getlegendbreak('polygon', **kwargs)
        pb.setCaption(label)
        
        #Create graphics
        graphics = GraphicFactory.createFillBetweenPolygonsX(ydata, x1, x2, where, pb)
        zorder = kwargs.pop('zorder', None)
        self.add_graphic(graphics, zorder=zorder)
        self._axes.setAutoExtent()

        return pb

    def pie(self, x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, 
        labeldistance=1.1, startangle=0, radius=None, wedgeprops=None, **kwargs):
        """
        Plot a pie chart.
        
        Make a pie chart of array *x*. The fraction area of each wedge is given by x/sum(x). If
        sum(x) <= 1, then the values of x give the fractional area directly and the array will not
        be normalized. The wedges are plotted counterclockwise, by default starting from the x-axis.
        
        :param explode: (*None | len(x)sequence) If not *None*, is a ``len(x)`` array which specifies
            the fraction of the radius with which to offset each wedge.
        :param labels: (*None | len(x) sequence of colors*] A sequence of strings providing the labels
            for each wedge.
        :param colors: (*None | color sequence*) A sequence of color args through which the pie chart
            will cycle.
        :param autopct: (*None | format string | format function) If not *None*, is a string or function
            used to label the wedges with their numeric value. The label will be placed inside the wedge.
            If it is a format string, the label will be ``fmt%pct``. If it is a function, it will be called.
        :param pctdistance: (*float*) The ratio between the center of each pie slice and the start of the
            text generated by *autopct*. Ignored if autopct is *None*; default is 0.6.
        :param labeldistance: (*float*) The ratial distance at which the pie labels are drawn.
        :param shadow: (*boolean*) Draw a shadow beneath the pie.
        :param startangle: (*float*) If not *0*, rotates the start of the pie chart by *angle* degrees
            counterclockwise from the x-axis.
        :param radius: (*float*) The radius of the pie, if *radius* is *None* it will be set to 1.
        :param wedgeprops: (*dict*) Dict of arguments passed to the wedge objects making the pie. 
        :param fontname: (*string*) Font name. Default is ``Arial`` .
        :param fontsize: (*int*) Font size. Default is ``14`` .
        
        :returns: (*tuple*) Patches and texts.
        """        
        n = len(x)
        x = plotutil.getplotdata(x)
        if colors is None:
            cmap = kwargs.pop('cmap', 'matlab_jet')
            colors = plotutil.makecolors(n, cmap=cmap)
        else:
            colors = plotutil.getcolors(colors)
            
        fontname = kwargs.pop('fontname', 'Arial')
        fontsize = kwargs.pop('fontsize', 14)
        bold = kwargs.pop('bold', False)
        fontcolor = kwargs.pop('fontcolor', 'black')
        if bold:
            font = Font(fontname, Font.BOLD, fontsize)
        else:
            font = Font(fontname, Font.PLAIN, fontsize)
        fontcolor = plotutil.getcolor(fontcolor)
        if radius is None:
            radius = 1
        if wedgeprops is None:
            wedgeprops = HashMap()
        else:
            jmap = HashMap()
            for key in wedgeprops.keys():
                value = wedgeprops[key]
                if key == 'edgecolor':
                    if value is None:
                        jmap['drawedge'] = False
                    else:
                        value = plotutil.getcolor(value)
                        jmap[key] = value
                else:
                    jmap[key] = value
            wedgeprops = jmap
        
        #Create graphics
        graphics = GraphicFactory.createPieArcs(x, colors, labels, startangle, explode, font, fontcolor, \
            labeldistance, autopct, pctdistance, radius, wedgeprops)

        for graphic in graphics:
            self.add_graphic(graphic)
        self._axes.setAutoExtent()
        self._axes.setAspectType(AspectType.EQUAL)
        self._axes.getAxis(Location.BOTTOM).setVisible(False)
        self._axes.getAxis(Location.LEFT).setVisible(False)
        self._axes.getAxis(Location.TOP).setVisible(False)
        self._axes.getAxis(Location.RIGHT).setVisible(False)

        return tuple(graphics)
        
    def boxplot(self, x, sym=None, vert=True, positions=None, widths=None, color=None, showcaps=True, showfliers=True, showmeans=False, \
            showmedians=True, meanline=False, medianline=True, boxprops=None, medianprops=None, meanprops=None, whiskerprops=None, capprops=None, flierprops=None):
        """
        Make a box and whisker plot.
        
        Make a box and whisker plot for each column of x or each vector in sequence x. The box extends from lower
        to upper quartile values of the data, with a line at the median. The whiskers extend from the box to show
        the range of the data. Flier points are those past the end of the whiskers.
        
        :param x: (*Array or a sequence of vectors*) The input data.
        :param sym: (*string*) The default symbol for flier points. Enter an empty string ('') if you don’t 
            want to show fliers. If None, then the fliers default to ‘b+’ If you want more control use the 
            flierprops kwarg.
        :param vert: (*boolean*) If True, draws vertical boxes (default). If False, draw horizontal boxes.
        :param positions: (*array_like*) Sets the positions of the boxes. The ticks and limits are automatically 
            set to match the positions. Defaults to range(1, N+1) where N is the number of boxes to be drawn.
        :param widths: (*scalar or array_like*) Sets the width of each box either with a scalar or a sequence. 
            The default is 0.5, or 0.15*(distance between extreme positions), if that is smaller.
        :param color: (*Color*) Color for all parts of the box plot. Defaul is None.
        :param showcaps: (*boolean*) Show the caps on the ends of whiskers. Default is ``True``.
        :param showfliers: (*boolean*) Show the outliers beyond the caps. Defaul is ``True``.
        :param showmeans: (*boolean*) Default is ``False``. Show the mean or not.
        :param showmedians: (*boolean*) Default is ``True``. Show the median or not.
        :param meanline: (*boolean*) Default is ``False``. If ``True`` (and showmeans is ``True``), will try to render
            the mean as a line spanning. Otherwise, means will be shown as points.
        :param medianline: (*boolean*) Default is ``True``. If ``True`` (and showmedians is ``True``), will try to render
            the median as a line spanning. Otherwise, medians will be shown as points.
        :param boxprops: (*dict*) Specifies the style of the box.
        :param medianprops: (*dict*) Specifies the style of the median.
        :param meanprops: (*dict*) Specifies the style of the mean.
        :param whiskerprops: (*dict*) Specifies the style of the whiskers.
        :param capprops: (*dict*) Specifies the style of the caps.
        :param flierprops: (*dict*) Specifies the style of the fliers.
        """
        if isinstance(x, list):
            x1 = []
            for a in x:
                x1.append(plotutil.getplotdata(a))
            x = x1
        else:
            x = plotutil.getplotdata(x)
            x = [x]
        
        if not positions is None:
            if isinstance(positions, (NDArray, DimArray)):
                positions = positions.tolist()
        
        if not widths is None:
            if isinstance(widths, (int, float)):
                nwidths = []
                for i in range(len(x)):
                    nwidths.append(widths)
                widths = nwidths
            elif isinstance(widths, (NDArray, DimArray)):
                widths = widths.tolist()
            
        #Get box plot properties
        if not color is None:
            color = plotutil.getcolor(color)
        if not sym is None:
            sym = plotutil.getplotstyle(sym, '')
            sym.setDrawFill(False)
            if not color is None:
                sym.setColor(color)
                sym.setOutlineColor(color)
        if boxprops is None:
            boxprops = PolygonBreak()
            boxprops.setDrawFill(False)
            boxprops.setOutlineColor(color is None and Color.blue or color)
        else:
            if not boxprops.has_key('facecolor'):
                boxprops['facecolor'] = None
            boxprops = plotutil.getlegendbreak('polygon', **boxprops)[0]
        if medianline:
            if medianprops is None:
                medianprops = PolylineBreak()
                medianprops.setColor(color is None and Color.red or color)
            else:
                medianprops = plotutil.getlegendbreak('line', **medianprops)[0]
        else:
            if medianprops is None:
                medianprops = PointBreak()
                medianprops.setColor(color is None and Color.blue or color)
            else:
                medianprops = plotutil.getlegendbreak('point', **medianprops)[0]
        if whiskerprops is None:
            whiskerprops = PolylineBreak()
            whiskerprops.setColor(color is None and Color.black or color)
            whiskerprops.setStyle(LineStyles.DASH)
        else:
            whiskerprops = plotutil.getlegendbreak('line', **whiskerprops)[0]
        if capprops is None:
            capprops = PolylineBreak()
            capprops.setColor(color is None and Color.black or color)
        else:
            capprops = plotutil.getlegendbreak('line', **capprops)[0]
        if meanline:
            if not meanprops is None:
                meanprops = plotutil.getlegendbreak('line', **meanprops)[0]
            else:
                meanprops = PolylineBreak()
                meanprops.setColor(color is None and Color.black or color)
        else:
            if meanprops is None:
                meanprops = PointBreak()
                meanprops.setStyle(PointStyle.SQUARE)
                meanprops.setColor(color is None and Color.red or color)
                meanprops.setOutlineColor(color is None and Color.black or color)
            else:
                meanprops = plotutil.getlegendbreak('point', **meanprops)[0]
        if not flierprops is None:
            flierprops = plotutil.getlegendbreak('point', **flierprops)[0]
        else:
            flierprops = sym
        if flierprops is None:
            flierprops = PointBreak()
            flierprops.setColor(color is None and Color.red or color)
            flierprops.setStyle(PointStyle.PLUS)
        
        #Create graphics
        if vert:
            graphics = GraphicFactory.createBox(x, positions, widths, showcaps, showfliers, showmeans, \
                showmedians, boxprops, medianprops, whiskerprops, capprops, meanprops, flierprops)
        else:
            graphics = GraphicFactory.createHBox(x, positions, widths, showcaps, showfliers, showmeans, \
                showmedians, boxprops, medianprops, whiskerprops, capprops, meanprops, flierprops)

        self.add_graphic(graphics)
        self._axes.setAutoExtent()

        return graphics
        
    def violinplot(self, dataset, positions=None, widths=0.5, boxwidth=0.01, boxprops=None, \
        whiskerprops=None, **kwargs):
        """
        Make a violin plot.
        
        :param dateset: (*Array or a sequence of vectors*) The input data.
        :param positions: (*array_like*) Sets the positions of the violins. The ticks and limits are automatically 
            set to match the positions. Defaults to range(1, N+1) where N is the number of violins to be drawn.
        :param widths: (*scalar or array_like*) Sets the width of each box either with a scalar or a sequence. 
            The default is 0.5, or 0.15*(distance between extreme positions), if that is smaller.   
        :param boxwidth: (*float*) box width.
        :param boxprops: (*dict*) Specifies the style of the box.
        :param whiskerprops: (*dict*) Specifies the style of the whiskers.
        
        :returns: Violin graphics.
        """
        if isinstance(dataset, NDArray):
            dataset = [dataset]
        n = len(dataset)
        
        if positions is None:
            positions = np.arange(1, n+1)
            
        graphics = []
        pdfs = []
        xx = []
        max = 0
        for data,position in zip(dataset, positions):
            if data.contains_nan():
                data = np.delnan(data)
            kde = np.stats.GaussianKDE(data)
            x = np.linspace(data.min(), data.max(), 100)            
            pdf = kde.evaluate(x)
            pdfs.append(pdf)
            xx.append(x)
            if pdf.max() > max:
                max = pdf.max()
            
        if boxprops is None:
            boxprops = dict(color='k',edgecolor=None)
        if whiskerprops is None:
            whiskerprops = whiskerprops=dict(color='k')
        if not kwargs.has_key('color'):
            kwargs['color'] = 'c'
        if not kwargs.has_key('edgecolor'):
            kwargs['edgecolor'] = 'b'
        ratio = widths / max
        for data,position,pdf,x in zip(dataset, positions, pdfs, xx):
            pdf = pdf * ratio
            self.fill_betweenx(x, position-pdf, position+pdf, **kwargs)
            ggs = self.boxplot(data, positions=[position], widths=boxwidth, showfliers=False, \
                showcaps=False, medianline=False, boxprops=boxprops, \
                whiskerprops=whiskerprops, medianprops=dict(color='w',edgecolor=None))
            graphics.extend(ggs)
        
        return graphics

    def taylor_diagram(self, stddev, correlation, std_max=1.65, labels=None, ref_std=1., colors=None,
                       **kwargs):
        """
        Create Taylor diagram.

        :param stddev: (*array*) Standard deviation.
        :param correlation: (*array*) Pattern correlations.
        :param ref_std: (*float*) Reference standard deviation. Default value is `1.`.
        :param std_max: (*float*) Maximum standard deviation. Default value is `1.651`.
        :param labels: (*list of string*) Data labels.
        :param colors: (*list of color*) Data points colors.
        :param markers: (*list of marker string*) Data points markers.
        :param sizes: (*list of int*) Data points sizes.
        :param std_max_axis_props: (*dict*) Property of the maximum standard deviation axis line.
        :param corr_tick_props: (*dict*) Property of the correlation tick lines.
        :param corr_tick_label_props: (*dict*) Property of the correlation tick labels.
        :param corr_label_props: (*dict*) Property of the correlation label.

        :returns: Axes and Taylor graphic.
        """
        #Set axes
        self.set_aspect('equal')
        self.set_clip(False)
        self.xaxis(location='top', visible=False)
        self.yaxis(location='right', visible=False)

        #plot RMS circle
        th = np.linspace(0, np.pi, 200)
        xunit = np.cos(th)
        yunit = np.sin(th)
        tickrms = np.arange(0.25, ref_std + 0.2, 0.25)
        radius = np.sqrt(ref_std**2 + std_max**2 -
                         2 * ref_std * std_max * xunit)
        for iradius in tickrms:
            phi = th[np.where(radius >= iradius)]
            if len(phi) > 0:
                phi = phi[0]
                ig = np.where(iradius * np.cos(th) + ref_std <=
                              std_max * np.cos(phi))
                self.plot(xunit[ig] * iradius + ref_std, yunit[ig] * iradius, color='gray')

        #plot stddev circle
        self.set_xlim(0, std_max)
        self.set_ylim(0, std_max)
        std_ticks = np.arange(0, std_max, 0.25)
        self.set_xticks(std_ticks)
        xtick_labels = []
        for std_tick in std_ticks:
            if std_tick == ref_std:
                xtick_labels.append('REF')
            else:
                xtick_labels.append(str(std_tick))
        self.set_xticklabels(xtick_labels)
        self.set_yticks(std_ticks)
        th = np.linspace(0, np.pi * 0.5, 200)
        xunit = np.cos(th)
        yunit = np.sin(th)
        xticks = self.get_xticks()
        for i in xticks:
            self.plot(xunit * i, yunit * i, color='gray', linestyle='--')
        std_max_axis_props = kwargs.pop('std_max_axis_props', dict(color='k'))
        self.plot(xunit * std_max, yunit * std_max, **std_max_axis_props)

        #plot correlation lines
        values = np.arange(0., 1., 0.1)
        values = values.join(np.array([0.95,0.99,1.0]), 0)
        corr_tick_props = kwargs.pop('corr_tick_props', dict(color='k'))
        corr_tick_label_props = kwargs.pop('corr_tick_label_props', dict(yalign='center'))
        if not corr_tick_label_props.has_key('yalign'):
            corr_tick_label_props['yalign'] = 'center'
        corr_label_props = kwargs.pop('corr_label_props', dict(xalign='center', yalign='bottom'))
        if not corr_label_props.has_key('xalign'):
            corr_label_props['xalign'] = 'center'
        if not corr_label_props.has_key('yalign'):
            corr_label_props['yalign'] = 'bottom'
        for t in values:
            theta = np.acos(t)
            x = np.cos(theta) * std_max
            y = np.sin(theta) * std_max
            if 0 < t < 1:
                if t == 0.6 or t == 0.9:
                    self.plot([0,x], [0,y], color='gray', linestyle=':')
                self.plot([x*0.98,x], [y*0.98,y], **corr_tick_props)
            x = x * 1.02
            y = y * 1.02
            self.text(x, y, str(t), rotation=np.degrees(theta), **corr_tick_label_props)
            if t == 0.7:
                self.text(x*1.1, y*1.1, 'Correlation', rotation=np.degrees(theta)-90,
                        **corr_label_props)

        values = np.arange(0.05, 0.9, 0.1)
        values = values.join(np.array([0.91,0.92,0.93,0.94,0.96,0.97,0.98]), 0)
        for t in values:
            theta = np.acos(t)
            x = np.cos(theta) * std_max
            y = np.sin(theta) * std_max
            self.plot([x*0.99,x], [y*0.99,y], **corr_tick_props)

        #plot data
        stddev = np.atleast_2d(stddev)
        correlation = np.atleast_2d(correlation)
        if not labels is None:
            labels = np.atleast_2d(labels)
        ncase = stddev.shape[0]
        if colors is None:
            cmap = kwargs.pop('cmap', 'matlab_jet')
            colors = plotutil.makecolors(ncase, cmap)
        gg = []
        markers = kwargs.pop('markers', [None] * ncase)
        sizes = kwargs.pop('sizes', [6] * ncase)
        for i in range(ncase):
            rho = stddev[i]
            theta = np.acos(correlation[i])
            x = np.cos(theta) * rho
            y = np.sin(theta) * rho
            gg.append(self.scatter(x, y, edge=False, c=colors[i], s=sizes[i], marker=markers[i]))
            if labels is None:
                lbs = []
                for j in range(len(rho)):
                    lbs.append(str(j+1))
            else:
                lbs = labels[i]
            for xx, yy, label in zip(x, y, lbs):
                self.text(xx, yy, label, color=colors[i], xalign='center', yalign='bottom', yshift=-sizes[i])

        self.set_xlim(0, std_max)
        self.set_ylim(0, std_max)

        xl = kwargs.pop('xlabel', None)
        if not xl is None:
            self.set_xlabel(xl)
        yl = kwargs.pop('ylabel', 'Standard Deviation (Normalized)')
        self.set_ylabel(yl)
        tt = kwargs.pop('title', None)
        if not tt is None:
            self.set_title(tt)
            self.set_title(' ', loc='left')

        return self, gg
        
    def barbs(self, *args, **kwargs):
        """
        Plot a 2-D field of barbs.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param u: (*array_like*) U component of the arrow vectors (wind field) or wind direction.
        :param v: (*array_like*) V component of the arrow vectors (wind field) or wind speed.
        :param z: (*array_like*) Optional, 2-D z value array.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level 
            barbs to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param fill_value: (*float*) Fill_value. Default is ``-9999.0``.
        :param isuv: (*boolean*) Is U/V or direction/speed data array pairs. Default is True.
        :param size: (*float*) Base size of the arrows.
        :param order: (*int*) Z-order of created layer for display.
        
        :returns: Barbs graphics.
        """
        ls = kwargs.pop('symbolspec', None)
        cmap = plotutil.getcolormap(**kwargs)
        fill_value = kwargs.pop('fill_value', -9999.0)
        order = kwargs.pop('order', None)
        isuv = kwargs.pop('isuv', True)
        n = len(args) 
        iscolor = False
        cdata = None
        xaxistype = None
        if n <= 3 or (n == 4 and isinstance(args[3], int)):
            x = args[0].dimvalue(1)
            y = args[0].dimvalue(0)
            x, y = np.meshgrid(x, y)
            u = args[0]
            v = args[1]
            if args[0].islondim(1):
                xaxistype = 'lon'
            elif args[0].islatdim(1):
                xaxistype = 'lat'
            elif args[0].istimedim(1):
                xaxistype = 'time'
            args = args[2:]
            if len(args) > 0:
                cdata = args[0]
                iscolor = True
                args = args[1:]
        elif n <= 6:
            x = args[0]
            y = args[1]
            u = args[2]
            v = args[3]
            args = args[4:]
            if len(args) > 0:
                cdata = args[0]
                iscolor = True
                args = args[1:]
        x = plotutil.getplotdata(x)
        y = plotutil.getplotdata(y)
        u = plotutil.getplotdata(u)
        v = plotutil.getplotdata(v)    
        
        if ls is None:
            if iscolor:
                if len(args) > 0:
                    cn = args[0]
                    ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), cn, cmap)
                else:
                    levs = kwargs.pop('levs', None)
                    if levs is None:
                        ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), cmap)
                    else:
                        if isinstance(levs, NDArray):
                            levs = levs.aslist()
                        ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), levs, cmap)
            else:    
                if cmap.getColorCount() == 1:
                    c = cmap.getColor(0)
                else:
                    c = Color.black
                ls = LegendManage.createSingleSymbolLegendScheme(ShapeTypes.POINT, c, 10)
            ls = plotutil.setlegendscheme_point(ls, **kwargs)
        
        if not cdata is None:
            cdata = plotutil.getplotdata(cdata)
        igraphic = GraphicFactory.createBarbs(x, y, u, v, cdata, ls, isuv)

        if not xaxistype is None:
            self.set_xaxis_type(xaxistype)
            self._axes.updateDrawExtent()

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(igraphic, zorder=zorder)
        self._axes.setAutoExtent()

        return igraphic
        
    def quiver(self, *args, **kwargs):
        """
        Plot a 2-D field of arrows.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param u: (*array_like*) U component of the arrow vectors (wind field) or wind direction.
        :param v: (*array_like*) V component of the arrow vectors (wind field) or wind speed.
        :param z: (*array_like*) Optional, 2-D z value array.
        :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level 
            vectors to draw, in increasing order.
        :param cmap: (*string*) Color map string.
        :param fill_value: (*float*) Fill_value. Default is ``-9999.0``.
        :param isuv: (*boolean*) Is U/V or direction/speed data array pairs. Default is True.
        :param size: (*float*) Base size of the arrows.
        :param overhang: (*float*) fraction that the arrow is swept back (0 overhang means 
            triangular shape). Can be negative or greater than one.
        :param zorder: (*int*) Z-order of created layer for display.
        
        :returns: Quiver graphics.
        """
        ls = kwargs.pop('symbolspec', None)
        cmap = plotutil.getcolormap(**kwargs)
        fill_value = kwargs.pop('fill_value', -9999.0)
        zorder = kwargs.pop('zorder', None)
        isuv = kwargs.pop('isuv', True)
        n = len(args) 
        iscolor = False
        cdata = None
        xaxistype = None
        if n < 4 or (n == 4 and isinstance(args[3], int)):
            u = args[0]
            v = args[1]
            if isinstance(u, DimArray):
                x = u.dimvalue(1)
                y = u.dimvalue(0)
                # if args[0].islondim(1):
                #     xaxistype = 'lon'
                # elif args[0].islatdim(1):
                #     xaxistype = 'lat'
                # elif args[0].istimedim(1):
                #     xaxistype = 'time'
            else:
                x = np.arange(u.shape[1])
                y = np.arange(u.shape[0])
            x, y = np.meshgrid(x, y)
            args = args[2:]
            if len(args) > 0:
                cdata = args[0]
                iscolor = True
                args = args[1:]
        elif n <= 6:
            x = args[0]
            y = args[1]
            u = args[2]
            v = args[3]
            args = args[4:]
            if len(args) > 0:
                cdata = args[0]
                iscolor = True
                args = args[1:]
        x = plotutil.getplotdata(x)
        y = plotutil.getplotdata(y)
        u = plotutil.getplotdata(u)
        v = plotutil.getplotdata(v)    
        
        if ls is None:
            if iscolor:
                if len(args) > 0:
                    cn = args[0]
                    ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), cn, cmap)
                else:
                    levs = kwargs.pop('levs', None)
                    if levs is None:
                        ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), cmap)
                    else:
                        if isinstance(levs, NDArray):
                            levs = levs.tolist()
                        ls = LegendManage.createLegendScheme(cdata.min(), cdata.max(), levs, cmap)
            else:    
                if cmap.getColorCount() == 1:
                    c = cmap.getColor(0)
                else:
                    c = Color.black
                ls = LegendManage.createSingleSymbolLegendScheme(ShapeTypes.POINT, c, 10)
            ls = plotutil.setlegendscheme_arrow(ls, **kwargs)
        
        if not cdata is None:
            cdata = plotutil.getplotdata(cdata)
        igraphic = GraphicFactory.createArrows(x, y, u, v, cdata, ls, isuv)

        if not xaxistype is None:
            self.set_xaxis_type(xaxistype)
            self._axes.updateDrawExtent()

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(igraphic, zorder=zorder)
        self._axes.setAutoExtent()

        return igraphic
        
    def quiverkey(self, *args, **kwargs):
        """
        Add a key to a quiver plot.
        
        :param Q: (*MILayer or GraphicCollection*) The quiver layer instance returned by a call to quiver/quiverm.
        :param X: (*float*) The location x of the key.
        :param Y: (*float*) The location y of the key.
        :param U: (*float*) The length of the key.
        :param label: (*string*) A string with the length and units of the key.
        :param coordinates=['axes'|'figure'|'data']: (*string*) Default: 'axes'. Coordinate system and units for
            *X, Y*. 'axes' and 'figure' are normalized coordinate system with 0,0 in the lower left and 
            1,1 in the upper right, 'data' are the axes data coordinates (used for the locations of the 
            vectors in the quiver plot itself).
        :param color: (*Color*) Overrides face and edge colors from Q.
        :param labelpos=['N'|'S'|'E'|'W']: (*string*) Position the label above, below, to the right, to
            the left of the arrow, respectively.
        :param labelsep: (*float*) Distance in pixel between the arrow and the label. Default is 5.
        :param labelcolor: (*Color*) Label color. Default to default is black.
        :param fontname: (*string*) Label font name. Default is ``Arial`` .
        :param fontsize: (*int*) Label font size. Default is ``12`` .
        :param bold: (*boolean*) Is bold font or not. Default is ``False`` .
        :param fontproperties: (*dict*) A dictionary with keyword arguments accepted by the FontProperties
            initializer: *family, style, variant, size, weight*.
        """
        wa = ChartWindArrow()
        Q = args[0]
        if isinstance(Q, MILayer):
            wa.setLayer(Q._layer)
        else:
            wa.setLayer(Q)
        x = args[1]
        y = args[2]
        wa.setX(x)
        wa.setY(y)
        u = args[3]
        wa.setLength(u)
        if len(args) == 5:
            label = args[4]
            wa.setLabel(label)

        coordinates = kwargs.pop('coordinates', 'axes')
        wa.setCoordinates(coordinates)
        arrowbreak, isunique = plotutil.getlegendbreak('point', **kwargs)
        arrowbreak = plotutil.point2arrow(arrowbreak, **kwargs)
        wa.setArrowBreak(arrowbreak)
        lcobj = kwargs.pop('labelcolor', 'k')
        lcolor = plotutil.getcolor(lcobj)
        wa.setLabelColor(lcolor)
        fontname = kwargs.pop('fontname', 'Arial')
        fontsize = kwargs.pop('fontsize', 12)
        bold = kwargs.pop('bold', False)
        if bold:
            font = Font(fontname, Font.BOLD, fontsize)
        else:
            font = Font(fontname, Font.PLAIN, fontsize)
        wa.setFont(font)
        labelsep = kwargs.pop('labelsep', None)
        if not labelsep is None:
            wa.setLabelSep(labelsep)
        bbox = kwargs.pop('bbox', None)
        if not bbox is None:
            fill = bbox.pop('fill', None)
            if not fill is None:
                wa.setFill(fill)
            facecolor = bbox.pop('facecolor', None)
            if not facecolor is None:
                facecolor = plotutil.getcolor(facecolor)
                wa.setFill(True)
                wa.setBackground(facecolor)
            edge = bbox.pop('edge', None)
            if not edge is None:
                wa.setDrawNeatline(edge)
            edgecolor = bbox.pop('edgecolor', None)
            if not edgecolor is None:
                edgecolor = plotutil.getcolor(edgecolor)
                wa.setNeatlineColor(edgecolor)
                wa.setDrawNeatline(True)
            linewidth = bbox.pop('linewidth', None)
            if not linewidth is None:
                wa.setNeatlineSize(linewidth)
                wa.setDrawNeatline(True)
        self._axes.setWindArrow(wa)
        
    def streamplot(self, *args, **kwargs):
        """
        Plot 3D streamline.
        
        :param x: (*array_like*) Optional. X coordinate array.
        :param y: (*array_like*) Optional. Y coordinate array.
        :param u: (*array_like*) U component of the arrow vectors (wind field) or wind direction.
        :param v: (*array_like*) V component of the arrow vectors (wind field) or wind speed.
        :param z: (*array_like*) Optional, 2-D z value array.
        :param color: (*Color*) Streamline color.
        :param fill_value: (*float*) Fill_value. Default is ``-9999.0``.
        :param isuv: (*boolean*) Is U/V or direction/speed data array pairs. Default is True.
        :param density: (*int*) Streamline density. Default is 4.
        :param zorder: (*int*) Z-order of streamline graphic for display.
        
        :returns: (*graphics*) 3D streamline graphics.
        """
        isuv = kwargs.pop('isuv', True)
        density = kwargs.pop('density', 4)
        n = len(args)
        if n < 4:
            u = args[0]
            v = args[1]
            y = u.dimvalue(0)
            x = u.dimvalue(1)
        else:
            x = args[0]
            y = args[1]
            u = args[2]
            v = args[3]
        alb, isunique = plotutil.getlegendbreak('line', **kwargs)
        if not kwargs.has_key('headwidth'):
            kwargs['headwidth'] = 8
        if not kwargs.has_key('overhang'):
            kwargs['overhang'] = 0.5
        alb = plotutil.line2stream(alb, **kwargs)
        
        igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array, 
            density, alb, isuv)

        zorder = kwargs.pop('zorder', None)
        self.add_graphic(igraphic, zorder=zorder)
        self._axes.setAutoExtent()

        return igraphic
        
    def get_legend(self):
        """
        Get legend of the axes.
        
        :return: Legend
        """
        return self._axes.getLegendScheme()
        
    def legend(self, *args, **kwargs):
        """
        Places a legend on the axes.
        
        :param breaks: (*ColorBreak*) Legend breaks (optional).
        :param labels: (*list of string*) Legend labels (optional).
        :param orientation: (*string*) Colorbar orientation: ``vertical`` or ``horizontal``.
        :param loc: (*string*) The location of the legend, including: 'upper right', 'upper left',
            'lower left', 'lower right', 'right', 'ceter left', 'center right', lower center',
            'upper center', 'center' and 'custom'. Default is 'upper right'.
        :param x: (*float*) Location x in normalized (0, 1) units when ``loc=custom`` .
        :param y: (*float*) Location y in normalized (0, 1) units when ``loc=custom`` .
        :param frameon: (*boolean*) Control whether a frame should be drawn around the legend. Default
            is True.
        :param facecolor: (*None or color*) Control the legend’s background color. Default is None which 
            set not draw background.
        :param fontname: (*string*) Label font name. Default is ``Arial`` .
        :param fontsize: (*int*) Label font size. Default is ``14`` .
        :param labelcolor: (*color*) Label string color. Defaul is ``black``.
        :param bold: (*boolean*) Is bold font or not. Default is ``False`` .
        :param title: (*string*) Title string.
        :param titlefontname: (*string*) Title font name.
        :param titlefontsize: (*int*) Title font size.
        :param titlecolor: (*color*) Title color. Default is ``black`` .
        :param breakspace: (*float*) Break space.
        :param markerscale: (*float*) Marker symbol scale.
        :param markerwidth: (*float*) Marker symbol width.
        :param markerheight: (*float*) Marker symbol height.
        :param ncol: (*float*) Column number of the legend.
        :param xshift: (*float*) X shift.
        :param yshift: (*float*) Y shift.
        
        :returns: (*ChartLegend*) The chart legend.
        """ 
        newlegend = kwargs.pop('newlegend', True)
        ols = self._axes.getLegendScheme()
        if newlegend:
            clegend = ChartLegend(ols)
        else:
            clegend = self._axes.getLegend()
        ls = kwargs.pop('legend', None)
        if len(args) > 0:
            if isinstance(args[0], MILayer):
                ls = args[0].legend()
                args = args[1:]
            elif isinstance(args[0], LegendScheme):
                ls = args[0]
                args = args[1:]
            elif isinstance(args[0], GraphicCollection):
                if not args[0].isSingleLegend():
                    ls = args[0].getLegendScheme()
                    args = args[1:]
        if ls is None:
            if len(args) > 0:
                lbs = []
                for lb in args[0]:
                    if isinstance(lb, Graphic):
                        lbs.append(lb.getLegend().clone())
                    elif isinstance(lb, MILayer):
                        lbs.extend(lb.legend().getLegendBreaks())
                    else:
                        lbs.append(lb)
                if len(args) == 2:
                    labels = args[1]
                    for i in range(0, len(lbs)):
                        lbs[i].setCaption(labels[i])
                if isinstance(lbs[0], basestring):
                    clegend.setTickCaptions(lbs)
                else:
                    ls = LegendScheme()
                    for lb in lbs:
                        ls.addLegendBreak(lb)
                    if len(lbs) == 1:
                        ls.setLegendType(LegendType.SINGLE_SYMBOL)
                    elif lbs[0].getStartValue() == lbs[1].getEndValue():
                        ls.setLegendType(LegendType.UNIQUE_VALUE)
                    else:
                        ls.setLegendType(LegendType.GRADUATED_COLOR)
                    if clegend is None:
                        clegend = ChartLegend(ls)
                        self._axes.setLegend(clegend)
                    else:
                        clegend.setLegendScheme(ls)
        else:
            if len(args) > 0:
                labels = args[0]
                for i in range(len(labels)):
                    if i < ls.getBreakNum():
                        ls.getLegendBreak(i).setCaption(labels[i])
            if clegend is None:
                clegend = ChartLegend(ls)
                self._axes.setLegend(clegend)
            else:
                clegend.setLegendScheme(ls)
            
        loc = kwargs.pop('loc', 'upper right')    
        lp = LegendPosition.fromString(loc)
        clegend.setPosition(lp)
        if lp == LegendPosition.CUSTOM:
            x = kwargs.pop('x', 0)
            y = kwargs.pop('y', 0)
            clegend.setX(x)
            clegend.setY(y) 
        orien = 'vertical'
        if lp == LegendPosition.UPPER_CENTER_OUTSIDE or lp == LegendPosition.LOWER_CENTER_OUTSIDE:
            orien = 'horizontal'
        orientation = kwargs.pop('orientation', orien)
        if orientation == 'horizontal':
            clegend.setPlotOrientation(PlotOrientation.HORIZONTAL)
        else:
            clegend.setPlotOrientation(PlotOrientation.VERTICAL)
        frameon = kwargs.pop('frameon', True)
        clegend.setDrawNeatLine(frameon)
        bcobj = kwargs.pop('background', None)
        bcobj = kwargs.pop('facecolor', bcobj)
        if bcobj is None:
            clegend.setDrawBackground(False)
        else:
            clegend.setDrawBackground(True)
            background = plotutil.getcolor(bcobj)
            clegend.setBackground(background)
        labelfontdic = kwargs.pop('labelfont', None)
        if labelfontdic is None:
            labelfont = plotutil.getfont_1(**kwargs)    
        else:
            labelfont = plotutil.getfont(labelfontdic)
        clegend.setTickLabelFont(labelfont)
        labelcolor = kwargs.pop('labelcolor', None)
        if not labelcolor is None:
            labelcolor = plotutil.getcolor(labelcolor)
            clegend.setTickLabelColor(labelcolor)
        title = kwargs.pop('title', None)
        if not title is None:
            titlefontdic = kwargs.pop('titlefont', None)
            exfont = False
            if titlefontdic is None:
                fontname = kwargs.pop('titlefontname', None)
                exfont = False
                if fontname is None:
                    fontname = 'Arial'
                else:
                    exfont = True
                fontsize = kwargs.pop('titlefontsize', 14)
                bold = kwargs.pop('titlebold', False)                  
                if bold:
                    titlefont = Font(fontname, Font.BOLD, fontsize)
                else:
                    titlefont = Font(fontname, Font.PLAIN, fontsize)                
            else:
                titlefont = plotutil.getfont(titlefontdic)
            title = ChartText(title, titlefont)
            title.setUseExternalFont(exfont)
            titlecolor = kwargs.pop('titlecolor', None)
            if not titlecolor is None:
                titlecolor = plotutil.getcolor(titlecolor)
                title.setColor(titlecolor)            
            title.setXAlign(XAlign.CENTER)
            title.setYAlign(YAlign.TOP)
            clegend.setLabel(title)
        breakspace = kwargs.pop('breakspace', None)
        if not breakspace is None:
            clegend.setBreakSpace(breakspace)
        markerscale = kwargs.pop('markerscale', None)
        if not markerscale is None:
            clegend.setSymbolScale(markerscale)
        markerwidth = kwargs.pop('markerwidth', None)
        markerheight = kwargs.pop('markerheight', None)
        if not markerwidth is None:
            clegend.setSymbolWidth(markerwidth)
        if not markerheight is None:
            clegend.setSymbolHeight(markerheight)
        ncol = kwargs.pop('ncol', None)
        if not ncol is None:
            clegend.setColumnNumber(ncol)
            clegend.setAutoRowColNum(False)
        xshift = kwargs.pop('xshift', None)
        if not xshift is None:
            clegend.setXShift(xshift)
        yshift = kwargs.pop('yshift', None)
        if not yshift is None:
            clegend.setYShift(yshift)
        if newlegend:
            self._axes.addLegend(clegend)

        return clegend
        
    def colorbar(self, mappable=None, **kwargs):
        """
        Add a colorbar to a plot.
        
        :param mappable: (*MapLayer | LegendScheme | List of ColorBreak*) The mappable in plot.
        :param cax: (*Plot*) None | axes object into which the colorbar will be drawn.
        :param cmap: (*string*) Color map name. Default is None.
        :param shrink: (*float*) Fraction by which to shrink the colorbar. Default is 1.0.
        :param orientation: (*string*) Colorbar orientation: ``vertical`` or ``horizontal``.
        :param aspect: (*int*) Ratio of long to short dimensions.
        :param fontname: (*string*) Font name. Default is ``Arial`` .
        :param fontsize: (*int*) Font size. Default is ``14`` .
        :param bold: (*boolean*) Is bold font or not. Default is ``False`` .
        :param label: (*string*) Label. Default is ``None`` .
        :param labelloc: (*string*) Label location ['in' | 'out' | 'top' | 'bottom' | 'left' | 'right'].
            Default is ``out``.
        :param labelshift: (*float*) Label location shift value. Default is None (value is 5).
        :param newlegend: (*boolean*) Add a new legend or replace existing one.
        :param extend: (*string*) {'neither', 'both', 'min', 'max'} If not 'neither', make pointed end(s)
            for out-of- range values. These are set for a given colormap using the colormap set_under and
            set_over methods.
        :param extendrect: (*boolean*) If ``True`` the minimum and maximum colorbar extensions will be
            rectangular (the default). If ``False`` the extensions will be triangular.
        :param extendfrac: [None | 'auto' | length] If set to *None*, both the minimum and maximum triangular
            colorbar extensions with have a length of 5% of the interior colorbar length (the default). If
            set to 'auto', makes the triangular colorbar extensions the same lengths as the interior boxes
            . If a scalar, indicates the length of both the minimum and maximum triangle colorbar extensions
            as a fraction of the interior colorbar length.
        :param ticks: [None | list of ticks] If None, ticks are determined automatically from the input.
        :param ticklabels: [None | list of ticklabels] Tick labels.
        :param tickin: (*boolean*) Draw tick line inside or outside of the colorbar.
        :param tickrotation: (*float*) Set tick label rotation angle.
        :param xshift: (*float*) X shift of the colorbar with pixel coordinate.
        :param yshift: (*float*) Y shift of the colorbar with pixel coordinate.
        :param vmintick: (*boolean*) Draw minimum value tick or not.
        :param vmaxtick: (*boolean*) Draw maximum value tick or not.
        :param minortick: (*boolean*) Draw minor tick line or not.
        :param minorticknum: (*int*) Minor tick line number between two adjacent major tick lines.
        """
        cmap = kwargs.pop('cmap', None)
        shrink = kwargs.pop('shrink', 1)
        orientation = kwargs.pop('orientation', 'vertical')
        aspect = kwargs.pop('aspect', 20)
        tickfontdic = kwargs.pop('tickfont', None)
        if tickfontdic is None:
            tickfont = plotutil.getfont_1(**kwargs)    
        else:
            tickfont = plotutil.getfont(tickfontdic)
        exfont = False
        labelfontdic = kwargs.pop('labelfont', None)
        if labelfontdic is None:
            labfontname = kwargs.pop('labelfontname', tickfont.getName())
            if labfontname is None:
                labfontname = tickfont.getName()
            else:
                exfont = True
            labfontsize = kwargs.pop('labelfontsize', tickfont.getSize())
            labbold = kwargs.pop('labelbold', tickfont.isBold())
            if labbold:
                labelfont = Font(labfontname, Font.BOLD, labfontsize)
            else:
                labelfont = Font(labfontname, Font.PLAIN, labfontsize)    
        else:
            labelfont = plotutil.getfont(labelfontdic)

        if mappable is None:
            ls = self.get_legend()
        else:
            if isinstance(mappable, MILayer):
                ls = mappable.legend()
            elif isinstance(mappable, LegendScheme):
                ls = mappable
            elif isinstance(mappable, GraphicCollection):
                ls = mappable.getLegendScheme()
            else:
                ls = plotutil.makelegend(mappable, **kwargs)
        
        newlegend = kwargs.pop('newlegend', True)
        if newlegend:
            legend = ChartColorBar(ls)
            self._axes.addLegend(legend)
        else:
            legend = self._axes.getLegend()
            if legend is None:
                legend = ChartColorBar(ls)
                self._axes.setLegend(legend)
            else:
                legend.setLegendScheme(ls)
        legend.setColorbar(True)   
        legend.setShrink(shrink)
        legend.setAspect(aspect)
        legend.setTickLabelFont(tickfont)
        label = kwargs.pop('label', None)
        if not label is None:
            label = ChartText(label, labelfont)
            label.setUseExternalFont(exfont)
            legend.setLabel(label)        
        labelloc = kwargs.pop('labelloc', None)
        if not labelloc is None:
            legend.setLabelLocation(labelloc)
        labelshift = kwargs.pop('labelshift', None)
        if not labelshift is None:
            legend.setLabelShift(labelshift)
        if orientation == 'horizontal':
            legend.setPlotOrientation(PlotOrientation.HORIZONTAL)
            legend.setPosition(LegendPosition.LOWER_CENTER_OUTSIDE)
        else:
            legend.setPlotOrientation(PlotOrientation.VERTICAL)
            legend.setPosition(LegendPosition.RIGHT_OUTSIDE)
        legend.setDrawNeatLine(False)
        extend = kwargs.pop('extend', 'neither')
        legend.setExtendType(extend)
        extendrect = kwargs.pop('extendrect', True)
        legend.setExtendRect(extendrect)
        extendfrac = kwargs.pop('extendfrac', None)
        if extendfrac == 'auto':
            legend.setAutoExtendFrac(True)
        tickvisible = kwargs.pop('tickvisible', None)
        if not tickvisible is None:
            legend.setTickVisible(tickvisible)
        tickin = kwargs.pop('tickin', None)
        if not tickin is None:
            legend.setInsideTick(tickin)
        ticklen = kwargs.pop('ticklen', None)
        if not ticklen is None:
            legend.setTickLength(ticklen)
        if kwargs.has_key('tickwidth'):
            tickwidth = kwargs.pop('tickwidth')
            legend.setTickWidth(tickwidth)
        if kwargs.has_key('tickcolor'):
            tickcolor = kwargs.pop('tickcolor')
            tickcolor = plotutil.getcolor(tickcolor)
            legend.setTickColor(tickcolor)
        ticks = kwargs.pop('ticks', None)
        if not ticks is None:
            if isinstance(ticks, NDArray):
                ticks = ticks.aslist()
            legend.setTickLocations(ticks)
        ticklabels = kwargs.pop('ticklabels', None)
        if not ticklabels is None:
            if isinstance(ticklabels, (NDArray, DimArray)):
                ticklabels = ticklabels.aslist()
            if ls.getLegendType() == LegendType.UNIQUE_VALUE:
                legend.setTickCaptions(ticklabels)
            else:
                if isinstance(ticklabels[0], (int, long, float)):
                    legend.setTickLabels_Number(ticklabels)
                else:
                    legend.setTickLabelText(ticklabels)
        tickrotation = kwargs.pop('tickrotation', None)
        if not tickrotation is None:
            legend.setTickLabelAngle(tickrotation)
        xshift = kwargs.pop('xshift', None)
        if not xshift is None:
            legend.setXShift(xshift)
        yshift = kwargs.pop('yshift', None)
        if not yshift is None:
            legend.setYShift(yshift)
        vmintick = kwargs.pop('vmintick', False)
        vmaxtick = kwargs.pop('vmaxtick', False)
        legend.setDrawMinLabel(vmintick)
        legend.setDrawMaxLabel(vmaxtick)
        if kwargs.has_key('edgecolor'):
            edgecolor = kwargs.pop('edgecolor')
            edgecolor = plotutil.getcolor(edgecolor)
            legend.setNeatLineColor(edgecolor)
        if kwargs.has_key('edgesize'):
            edgesize = kwargs.pop('edgesize')
            legend.setNeatLineSize(edgesize)
        minortick = kwargs.pop('minortick', None)
        if not minortick is None:
            legend.setDrawMinorTick(minortick)

        return legend


###############################################
class PolarAxes(Axes):
    """
    Axes with polar coordinate.
    """
    
    def __init__(self, *args, **kwargs):
        super(PolarAxes, self).__init__(*args, **kwargs)

        bottom = kwargs.pop('bottom', None)
        if not bottom is None:
            self._axes.setBottom(bottom)
        
    def _set_plot(self, plot):
        """
        Set plot.
        
        :param plot: (*PolarPlot*) Plot.
        """
        if plot is None:
            self._axes = PolarPlot()
        else:
            self._axes = plot
        
    @property
    def axestype(self):
        return 'polar'
    
    def set_rmax(self, rmax):
        """
        Set radial max circle.
        
        :param rmax: (*float*) Radial max value.
        """
        self._axes.setRadius(rmax)
        
    def set_rlabel_position(self, pos):
        """
        Updates the theta position of the radial labels.
        
        :param pos: (*float*) The angular position of the radial labels in degrees.
        """
        if isinstance(pos, (DimArray, NDArray)):
            pos = pos.tolist()
        self._axes.setYTickLabelPos(pos)
        
    def set_rticks(self, ticks):
        """
        Set radial ticks.
        
        :param ticks: (*string list*) Tick labels.
        """
        self._axes.setYTickLabels(ticks)
        
    def set_rtick_format(self, fmt=''):
        """
        Set radial tick format.
        
        :param ftm: (*string*) Tick format ['' | '%'].
        """
        self._axes.setYTickFormat(fmt)
        
    def set_rtick_locations(self, loc):
        """
        Set radial tick locations.
        
        :param loc: (*float list*) Tick locations.
        """
        if isinstance(loc, (DimArray, NDArray)):
            loc = loc.tolist()
        self._axes.setYTickLocations(loc)
        
    def set_xtick_locations(self, loc):
        """
        Set angular tick locations.
        
        :param loc: (*float list*) Tick locations.
        """
        if isinstance(loc, (DimArray, NDArray)):
            loc = loc.tolist()
        self._axes.setXTickLocations(loc)
        
    def set_xticks(self, ticks):
        """
        Set angular ticks.
        
        :param ticks: (*string list*) Tick labels.
        """
        self._axes.setXTickLabels(ticks)
        
    def set_rtick_font(self, name=None, size=None, style=None):
        """
        Set radial tick font.
        
        :param name: (*string*) Font name.
        :param size: (*int*) Font size.
        :param style: (*string*) Font style.
        """
        font = self._axes.getYTickFont()
        if name is None:
            name = font.getName()
        if size is None:
            size = font.getSize()
        if style is None:
            style = font.getStyle()
        else:
            if style.lower() == 'bold':
                style = Font.BOLD
            elif style.lower() == 'italic':
                style = Font.ITALIC
            else:
                style = Font.PLAIN
        font = Font(name, style, size)
        self._axes.setYTickFont(font)

    def set_rtick_color(self, color):
        """
        Set radial tick label color

        :param color: (*color*) The color.
        """
        color = plotutil.getcolor(color)
        self._axes.setYTickColor(color)
        
    def set_xtick_font(self, name=None, size=None, style=None):
        """
        Set angular tick font.
        
        :param name: (*string*) Font name.
        :param size: (*int*) Font size.
        :param style: (*string*) Font style.
        """
        font = self._axes.getXTickFont()
        if name is None:
            name = font.getName()
        if size is None:
            size = font.getSize()
        if style is None:
            style = font.getStyle()
        else:
            if style.lower() == 'bold':
                style = Font.BOLD
            elif style.lower() == 'italic':
                style = Font.ITALIC
            else:
                style = Font.PLAIN
        font = Font(name, style, size)
        self._axes.setXTickFont(font)

    def set_xtick_color(self, color):
        """
        Set angular tick label color

        :param color: (*color*) The color.
        """
        color = plotutil.getcolor(color)
        self._axes.setXTickColor(color)
        
    def data2pixel(self, x, y, z=None):
        """
        Transform data coordinate to screen coordinate
        
        :param x: (*float*) X coordinate.
        :param y: (*float*) Y coordinate.
        :param z: (*float*) Z coordinate - only used for 3-D axes.
        """
        r = MIMath.polarToCartesian(x, y) 
        x = r[0]
        y = r[1]
        rect = self._axes.getPositionArea()
        r = self._axes.projToScreen(x, y, rect)
        sx = r[0] + rect.getX()
        sy = r[1] + rect.getY()
        sy = self.figure.get_size()[1] - sy
        return sx, sy

    def windrose(self, wd, ws, nwdbins=16, wsbins=None, degree=True, colors=None, cmap='matlab_jet', \
                 alpha=0.7, rmax=None, rtickloc=None, rticks=None, rlabelpos=60, xticks=None, **kwargs):
        """
        Plot windrose chart.

        :param wd: (*array_like*) Wind direction.
        :param ws: (*array_like*) Wind speed.
        :param nwdbins: (*int*) Number of wind direction bins [4 | 8 | 16].
        :param wsbins: (*array_like*) Wind speed bins.
        :param degree: (*boolean*) The unit of wind direction is degree or radians.
        :param colors: (*color list*) The colors.
        :param cmap: (*string*) Color map.
        :param alpha: (*float*) Color alpha (0 - 1).
        :param rmax: (*float*) Radial maximum value.
        :param rtickloc: (*list of float*) Radial tick locations.
        :param rticks: (*list of string*) Radial ticks.
        :param rlabelpos: (*float*) Radial label position in degree.
        :param xticks: (*list of string*) X ticks.

        :returns: Polar axes and bars
        """
        if not nwdbins in [4, 8, 16]:
            print('nwdbins must be 4, 8 or 16!')
            raise ValueError(nwdbins)

        if isinstance(wd, list):
            wd = np.array(wd)
        if isinstance(ws, list):
            ws = np.array(ws)

        wdbins = np.linspace(0.0, 2 * np.pi, nwdbins + 1)
        if wsbins is None:
            wsbins = np.arange(0., ws.max(), 2.).tolist()
            wsbins.append(100)
            wsbins = np.array(wsbins)

        dwdbins = np.degrees(wdbins)
        dwdbins = dwdbins - 90
        for i in range(len(dwdbins)):
            if dwdbins[i] < 0:
                dwdbins[i] += 360
        for i in range(len(dwdbins)):
            d = dwdbins[i]
            d = 360 - d
            dwdbins[i] = d
        rwdbins = np.radians(dwdbins)

        N = len(wd)
        wdN = nwdbins
        wsN = len(wsbins) - 1
        if colors is None:
            colors = plotutil.makecolors(wsN, cmap=cmap, alpha=alpha)

        wd = wd + 360./wdN/2
        wd[wd>360] = wd - 360
        rwd = np.radians(wd)

        width = kwargs.pop('width', 0.5)
        if width > 1:
            width = 1
        if width <= 0:
            width = 0.2
        theta = rwdbins[:-1]
        width = 2. * width * np.pi / wdN

        bars = []
        hhist = 0
        rrmax = 0
        for i in range(wsN):
            idx = np.where((ws>=wsbins[i]) * (ws<wsbins[i+1]))
            if idx is None:
                continue
            print(wsbins[i], wsbins[i+1])
            s_wd = rwd[idx]
            wdhist = np.histogram(s_wd, wdbins)[0].astype('float')
            wdhist = wdhist / N
            rrmax = max(rrmax, wdhist.max())
            lab = '%s - %s' % (wsbins[i], wsbins[i+1])
            bb = self.bar(theta, wdhist, width, bottom=hhist, color=colors[i], \
                     edgecolor='gray', label=lab, morepoints=True)[0]
            bb.setStartValue(wsbins[i])
            bb.setEndValue(wsbins[i+1])
            bars.append(bb)
            hhist = hhist + wdhist

        if rmax is None:
            rmax = math.ceil(rrmax)
        self.set_rmax(rmax)
        if not rtickloc is None:
            self.set_rtick_locations(rtickloc)
        if not rticks is None:
            self.set_rticks(rticks)
        self.set_rtick_format('%')
        self.set_rlabel_position(rlabelpos)
        self.set_xtick_locations(np.arange(0., 360., 360./wdN))
        step = 16 / nwdbins
        if xticks is None:
            xticks = ['E','ENE','NE','NNE','N','NNW','NW','WNW','W','WSW', \
                      'SW','SSW','S','SSE','SE','ESE']
            xticks = xticks[::step]
        elif not xticks:
            xticks = [''] * nwdbins
        self.set_xticks(xticks)
        return bars
