mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
4451 lines
172 KiB
Python
4451 lines
172 KiB
Python
# 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.geometry.legend import BarBreak, PolygonBreak, PolylineBreak, \
|
||
PointBreak, LineStyles, PointStyle, LegendScheme, LegendType, LegendManage, ExtendFraction
|
||
from org.meteoinfo.geometry.shape import ShapeTypes
|
||
from org.meteoinfo.geometry.graphic import Graphic, GraphicCollection, ImageGraphic
|
||
from org.meteoinfo.geometry.colors import ExtendType
|
||
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
|
||
from .graphic import Line2D, Artist, Point2DCollection
|
||
|
||
__all__ = ['Axes', 'PolarAxes']
|
||
|
||
|
||
class Axes(object):
|
||
"""
|
||
Axes with Cartesian coordinate.
|
||
"""
|
||
|
||
def __init__(self, *args, **kwargs):
|
||
self._stale = True
|
||
|
||
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')
|
||
frameon = kwargs.pop('frameon', None)
|
||
if frameon is not None:
|
||
self._axes.setDrawNeatLine(frameon)
|
||
|
||
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)
|
||
facecolor = kwargs.pop('bgcolor', None)
|
||
facecolor = kwargs.pop('facecolor', facecolor)
|
||
|
||
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)
|
||
if facecolor is not None:
|
||
facecolor = plotutil.getcolor(facecolor)
|
||
self._axes.setBackground(facecolor)
|
||
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 stale(self):
|
||
return self._stale
|
||
|
||
@stale.setter
|
||
def stale(self, val):
|
||
self._stale = val
|
||
self._axes.setAutoExtent()
|
||
|
||
if self._figure is not None:
|
||
self._figure.stale = val
|
||
|
||
@property
|
||
def figure(self):
|
||
return self._figure
|
||
|
||
@figure.setter
|
||
def figure(self, val):
|
||
self._figure = val
|
||
|
||
@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', **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.
|
||
"""
|
||
if not kwargs.has_key('bold'):
|
||
kwargs['bold'] = True
|
||
if not kwargs.has_key('xalign'):
|
||
kwargs['xalign'] = 'center'
|
||
title = plotutil.text(0, 0, label, **kwargs)
|
||
|
||
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)
|
||
ax.setAutoExtent()
|
||
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)
|
||
ax.setAutoExtent()
|
||
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 set_axis_on(self):
|
||
"""
|
||
Set all axis visible.
|
||
"""
|
||
self.get_axis(Location.BOTTOM).setVisible(True)
|
||
self.get_axis(Location.LEFT).setVisible(True)
|
||
self.get_axis(Location.TOP).setVisible(True)
|
||
self.get_axis(Location.RIGHT).setVisible(True)
|
||
|
||
def set_axis_off(self):
|
||
"""
|
||
Set all axis not visible.
|
||
"""
|
||
self.get_axis(Location.BOTTOM).setVisible(False)
|
||
self.get_axis(Location.LEFT).setVisible(False)
|
||
self.get_axis(Location.TOP).setVisible(False)
|
||
self.get_axis(Location.RIGHT).setVisible(False)
|
||
|
||
def axis(self, arg=None, **kwargs):
|
||
"""
|
||
Convenience method to get or set some axis properties.
|
||
|
||
Call signatures::
|
||
xmin, xmax, ymin, ymax = axis()
|
||
xmin, xmax, ymin, ymax = axis([xmin, xmax, ymin, ymax])
|
||
xmin, xmax, ymin, ymax = axis(option)
|
||
xmin, xmax, ymin, ymax = axis(**kwargs)
|
||
|
||
Parameters
|
||
----------
|
||
xmin, xmax, ymin, ymax : float, optional
|
||
The axis limits to be set. This can also be achieved using ::
|
||
ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))
|
||
|
||
option : bool or str
|
||
If a bool, turns axis lines and labels on or off. If a string,
|
||
possible values are:
|
||
======== ==========================================================
|
||
Value Description
|
||
======== ==========================================================
|
||
'on' Turn on axis lines and labels. Same as ``True``.
|
||
'off' Turn off axis lines and labels. Same as ``False``.
|
||
'equal' Set equal scaling (i.e., make circles circular) by
|
||
changing axis limits. This is the same as
|
||
``ax.set_aspect('equal', adjustable='datalim')``.
|
||
Explicit data limits may not be respected in this case.
|
||
'scaled' Set equal scaling (i.e., make circles circular) by
|
||
changing dimensions of the plot box. This is the same as
|
||
``ax.set_aspect('equal', adjustable='box', anchor='C')``.
|
||
Additionally, further autoscaling will be disabled.
|
||
'tight' Set limits just large enough to show all data, then
|
||
disable further autoscaling.
|
||
'auto' Automatic scaling (fill plot box with data).
|
||
'image' 'scaled' with axis limits equal to data limits.
|
||
'square' Square plot; similar to 'scaled', but initially forcing
|
||
``xmax-xmin == ymax-ymin``.
|
||
======== ==========================================================
|
||
|
||
Returns
|
||
-------
|
||
xmin, xmax, ymin, ymax : float
|
||
The axis limits.
|
||
"""
|
||
if isinstance(arg, (str, bool)):
|
||
if arg is True:
|
||
arg = 'on'
|
||
if arg is False:
|
||
arg = 'off'
|
||
arg = arg.lower()
|
||
if arg == 'on':
|
||
self.set_axis_on()
|
||
elif arg == 'off':
|
||
self.set_axis_off()
|
||
elif arg in ['auto', 'equal']:
|
||
self.set_aspect(arg)
|
||
else:
|
||
raise ValueError("Unrecognized string {} to axis; "
|
||
"try 'on' or 'off'".format(arg))
|
||
else:
|
||
if arg is not None:
|
||
try:
|
||
xmin, xmax, ymin, ymax = arg
|
||
except (TypeError, ValueError) as err:
|
||
raise TypeError('the first argument to axis() must be an '
|
||
'iterable of the form '
|
||
'[xmin, xmax, ymin, ymax]')
|
||
self.set_xlim(xmin, xmax)
|
||
self.set_ylim(ymin, ymax)
|
||
|
||
return self.get_xlim() + self.get_ylim()
|
||
|
||
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 set_draw_extent(self, extent):
|
||
"""
|
||
Set axes draw extent.
|
||
|
||
:param extent: The extent
|
||
"""
|
||
if not self._axes.isFixDrawExtent():
|
||
self._axes.setDrawExtent(extent.clone())
|
||
self._axes.setExtent(extent.clone())
|
||
|
||
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 or list of graphics*) The patch(s) to be added.
|
||
"""
|
||
if isinstance(patch, (list, tuple)):
|
||
self._axes.addGraphics(patch)
|
||
else:
|
||
self._axes.addGraphic(patch)
|
||
#self._axes.setAutoExtent()
|
||
self.stale = True
|
||
|
||
def add_graphic(self, graphic, transform=None, zorder=None):
|
||
"""
|
||
Add a graphic
|
||
|
||
:param graphic: (*Graphic*) The graphic to be added.
|
||
:param transform: (*Transform*) The transform. Default is `None`.
|
||
:param zorder: (*int*) Z order of the graphic. Default is `None` that the graphic added
|
||
to the end.
|
||
"""
|
||
if isinstance(graphic, Artist):
|
||
graphic.axes = self
|
||
|
||
if not zorder is None:
|
||
if zorder > self.num_graphics():
|
||
zorder = self.num_graphics()
|
||
|
||
if transform is None:
|
||
if zorder is None:
|
||
rGraphic = self._axes.addGraphic(graphic)
|
||
else:
|
||
rGraphic = self._axes.addGraphic(zorder, graphic)
|
||
else:
|
||
if zorder is None:
|
||
rGraphic = self._axes.addGraphic(graphic, transform)
|
||
else:
|
||
rGraphic = self._axes.addGraphic(zorder, graphic, transform)
|
||
|
||
#self._axes.setAutoExtent()
|
||
self.stale = True
|
||
return rGraphic
|
||
|
||
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.
|
||
"""
|
||
if isinstance(graphic, int):
|
||
if graphic < 0:
|
||
graphic = self._axes.getGraphicNumber() + graphic
|
||
|
||
self._axes.getGraphics().remove(graphic)
|
||
self.stale = True
|
||
|
||
def remove(self):
|
||
"""
|
||
Remove all graphics.
|
||
"""
|
||
self._axes.getGraphics().clear()
|
||
self.stale = True
|
||
|
||
def cll(self):
|
||
"""
|
||
Remove last graphic.
|
||
"""
|
||
self._axes.removeLastGraphic()
|
||
self.stale = True
|
||
|
||
def clear(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 color: (*color*) Line color.
|
||
:param alpha: (*float*) Color alpha.
|
||
:param linewidth: (*float*) Line width.
|
||
:param linestyle: (*str*) Line dash style.
|
||
:param top: (*bool*) Plot grid line on top of the graphics or not.
|
||
"""
|
||
gridline = self._axes.getGridLine()
|
||
is_draw = gridline.isDrawXLine()
|
||
if b is None:
|
||
if len(kwargs) == 0:
|
||
b = not is_draw
|
||
else:
|
||
b = True
|
||
|
||
if 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:
|
||
alpha = kwargs.pop('alpha', None)
|
||
c = plotutil.getcolor(color, alpha)
|
||
gridline.setColorAndAlpha(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)
|
||
|
||
return gridline
|
||
|
||
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.
|
||
:param linewidth: (*float*) Line width.
|
||
:param color: (*Color*) Line color.
|
||
|
||
:returns: 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:
|
||
ydata = np.array(args[0])
|
||
if isinstance(ydata, DimArray):
|
||
xdata = ydata.dimvalue(0)
|
||
if ydata.ndim == 2:
|
||
xdata = xdata[:,np.newaxis].repeat(ydata.shape[1], axis=1)
|
||
else:
|
||
xdata = np.arange(ydata.shape[0])
|
||
if ydata.ndim == 2:
|
||
xdata = xdata[:,np.newaxis].repeat(ydata.shape[1], axis=1)
|
||
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 = xdata[:,np.newaxis].repeat(ydata.shape[1], axis=1)
|
||
else:
|
||
xdata = np.arange(ydata.shape[0])
|
||
if ydata.ndim == 2:
|
||
xdata = xdata[:,np.newaxis].repeat(ydata.shape[1], axis=1)
|
||
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)
|
||
cdata = kwargs.pop('cdata', zvalues)
|
||
if cdata 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(cdata, (list, tuple)):
|
||
cdata = np.array(cdata)
|
||
levels = kwargs.pop('levs', None)
|
||
levels = kwargs.pop('levels', levels)
|
||
if levels is None:
|
||
cnum = kwargs.pop('cnum', None)
|
||
if cnum is None:
|
||
ls = plotutil.getlegendscheme([], cdata.min(), cdata.max(), **kwargs)
|
||
else:
|
||
ls = plotutil.getlegendscheme([cnum], cdata.min(), cdata.max(), **kwargs)
|
||
else:
|
||
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.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('curve', False)
|
||
graphics = []
|
||
if cdata is None:
|
||
# Add data series
|
||
snum = len(xdatalist)
|
||
if snum == 1:
|
||
xdata = np.asarray(xdatalist[0])
|
||
ydata = np.asarray(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._array, ydata._array, lines, iscurve)
|
||
else:
|
||
if ydata.ndim == 1:
|
||
graphic = Line2D(xdata, ydata, legend=lines[0], curve=iscurve)
|
||
else:
|
||
if xdata.ndim == 1:
|
||
xdata = xdata[:,np.newaxis].repeat(ydata.shape[1], axis=1)
|
||
graphic = GraphicFactory.createLineString(xdata._array, ydata._array, lines[0], iscurve)
|
||
else: # >1
|
||
graphic = GraphicFactory.createLineString(xdata._array, ydata._array, 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 = np.asarray(xdatalist[i])
|
||
ydata = np.asarray(ydatalist[i])
|
||
graphic = Line2D(xdata, ydata, legend=lines[i], curve=iscurve)
|
||
self.add_graphic(graphic)
|
||
graphics.append(graphic)
|
||
else:
|
||
xdata = np.asarray(xdatalist[0])
|
||
ydata = np.asarray(ydatalist[0])
|
||
cdata = np.asarray(cdata)
|
||
graphic = Line2D(xdata, ydata, legend=ls, cdata=cdata, curve=iscurve)
|
||
self.add_graphic(graphic, zorder=zorder)
|
||
graphics.append(graphic)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
for graphic in graphics:
|
||
graphic.setAntiAlias(antialias)
|
||
|
||
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)
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
|
||
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 point series.
|
||
:param levels: (*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)
|
||
graphics = Point2DCollection(xdata, ydata, c._array, legend=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)
|
||
graphics = Point2DCollection(xdata, ydata, legend=pbs)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
|
||
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()
|
||
eline.setDrawPolyline(True)
|
||
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)
|
||
|
||
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)
|
||
if autowidth:
|
||
barswidth = kwargs.pop('barswidth', 0.8)
|
||
self._axes.setBarsWidth(barswidth)
|
||
|
||
return graphics
|
||
|
||
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 without ``width`` augment). Default is 0.8.
|
||
: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')
|
||
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)
|
||
|
||
if autoheight:
|
||
barsheight = kwargs.pop('barsheight', 0.8)
|
||
self._axes.setBarsWidth(barsheight)
|
||
|
||
return graphics
|
||
|
||
def hist(self, x, bins=10, density=False, cumulative=False,
|
||
rwidth=None, orientation='vertical', **kwargs):
|
||
"""
|
||
Plot a histogram.
|
||
|
||
:param x: (*array_like*) Input values, this takes either a single array or a sequence 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.
|
||
:param density: (*bool*) Default is `False`. If `True`, draw and return a probability
|
||
density: each bin will display the bin's raw count divided by the total number of
|
||
counts and the bin width
|
||
:param cumulative: (*bool*) Default is `False`. If `True`, then a histogram is computed
|
||
where each bin gives the counts in that bin plus all bins for smaller values. The
|
||
last bin gives the total number of datapoints.
|
||
:param rwidth: (*float or None*) Default is `None`. The relative width of the bars as a
|
||
fraction of the bin width. If None, automatically compute the width.
|
||
:param orientation: (*str*) {'vertical', 'horizontal'}, default: 'vertical'. If
|
||
'horizontal', barh will be used for bar-type histograms and the bottom kwarg will be
|
||
the left edges.
|
||
|
||
Returns
|
||
-------
|
||
n : array or list of arrays
|
||
The values of the histogram bins. See *density* and *weights* for a
|
||
description of the possible semantics. If input *x* is an array,
|
||
then this is an array of length *nbins*. If input is a sequence of
|
||
arrays ``[data1, data2, ...]``, then this is a list of arrays with
|
||
the values of the histograms for each of the arrays in the same
|
||
order. The dtype of the array *n* (or of its element arrays) will
|
||
always be float even if no weighting or normalization is used.
|
||
bins : array
|
||
The edges of the bins. Length nbins + 1 (nbins left edges and right
|
||
edge of last bin). Always a single array even when multiple data
|
||
sets are passed in.
|
||
patches : `.BarContainer` or list of a single `.Polygon` or list of such objects
|
||
Container of individual artists used to create the histogram
|
||
or list of such containers if there are multiple input datasets.
|
||
"""
|
||
if isinstance(x, NDArray) and x.ndim == 1:
|
||
m, bins = np.histogram(x, bins=bins, density=density)
|
||
width = np.diff(bins)
|
||
if cumulative:
|
||
m = np.cumsum(m * width)
|
||
|
||
if rwidth is not None:
|
||
width = width * rwidth
|
||
|
||
if orientation == 'vertical':
|
||
barbreaks = self.bar(bins[:-1], m, width, align='center', **kwargs)
|
||
else:
|
||
barbreaks = self.barh(bins[:-1], m, width, align='center', **kwargs)
|
||
|
||
return m, bins, barbreaks
|
||
else:
|
||
mlist = []
|
||
barbreaklist = []
|
||
if isinstance(x, (list, tuple)):
|
||
n = len(x)
|
||
else:
|
||
n = x.shape[1]
|
||
|
||
colors = kwargs.pop('color', None)
|
||
if colors is None:
|
||
colors = plotutil.makecolors(n)
|
||
labels = kwargs.pop('label', None)
|
||
|
||
for i in range(n):
|
||
if isinstance(x, NDArray):
|
||
xx = x[:,i]
|
||
else:
|
||
xx = x[i]
|
||
|
||
m, bins = np.histogram(xx, bins=bins, density=density)
|
||
width = np.diff(bins) / n
|
||
if cumulative:
|
||
m = np.cumsum(m * width)
|
||
mlist.append(m)
|
||
if rwidth is not None:
|
||
width = width * rwidth
|
||
kwargs['color'] = colors[i]
|
||
if labels is not None:
|
||
kwargs['label'] = labels[i]
|
||
if orientation == 'vertical':
|
||
barbreaks = self.bar(bins[:-1] + width * i, m, width, align='center', **kwargs)
|
||
else:
|
||
barbreaks = self.barh(bins[:-1] + width * i, m, width, align='center', **kwargs)
|
||
barbreaklist.append(barbreaks)
|
||
|
||
return mlist, bins, barbreaklist
|
||
|
||
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)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
|
||
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 levels: (*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 contour lines or not.
|
||
|
||
:returns: (*contour graphics*) Contour graphics created from array data.
|
||
"""
|
||
n = len(args)
|
||
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())
|
||
ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
|
||
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)
|
||
graphics = GraphicFactory.createContourLines(x.asarray(), y.asarray(), a.asarray(), ls, smooth)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
self.set_draw_extent(graphics.getExtent())
|
||
|
||
return graphics
|
||
|
||
def clabel(self, layer, **kwargs):
|
||
"""
|
||
Add contour layer labels.
|
||
|
||
:param layer: (*MILayer*) The contour layer.
|
||
:param fontname, fontsize: The font augments.
|
||
: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 levels: (*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 extend: (*string*) {'neither', 'both', 'min', 'max'}, default: 'neither'. Determines the
|
||
contourf-coloring of values that are outside the levels range. If 'neither', values outside
|
||
the levels range are not colored. If 'min', 'max' or 'both', color the values below, above
|
||
or below and above the levels range.
|
||
:param extendfrac: (*string or float*) {None, 'auto', length}, If set to None, both the minimum
|
||
and maximum triangular colorbar extensions will have a length of 5% of the interior colorbar
|
||
length (this is the default setting). 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 triangular colorbar extensions as a fraction of the interior colorbar
|
||
length.
|
||
:param smooth: (*boolean*) Smooth contour lines or not.
|
||
|
||
:returns: (*GraphicCollection*) Contour filled graphics 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 not kwargs.has_key('extend'):
|
||
kwargs['extend'] = 'neither'
|
||
ls = plotutil.getlegendscheme(args, vmin, vmax, **kwargs)
|
||
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)
|
||
|
||
graphics = GraphicFactory.createContourPolygons(x.asarray(), y.asarray(), a.asarray(), ls, smooth)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
visible = kwargs.pop('visible', True)
|
||
if visible:
|
||
if xaxistype is not None:
|
||
self.set_xaxis_type(xaxistype)
|
||
self._axes.updateDrawExtent()
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
self.set_draw_extent(graphics.getExtent())
|
||
|
||
return graphics
|
||
|
||
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 levels: (*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:
|
||
if isinstance(X, DimArray):
|
||
xdata = X.dimvalue(-1)
|
||
ydata = X.dimvalue(-2)
|
||
else:
|
||
ny, nx = X.shape
|
||
xdata = np.arange(nx)
|
||
ydata = np.arange(ny)
|
||
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', X.min())
|
||
vmax = kwargs.pop('vmax', X.max())
|
||
if len(args) > 0:
|
||
level_arg = args[0]
|
||
if isinstance(level_arg, int):
|
||
cn = level_arg
|
||
ls = LegendManage.createImageLegend(X._array, cn, cmap)
|
||
else:
|
||
if isinstance(level_arg, NDArray):
|
||
level_arg = level_arg.aslist()
|
||
ls = LegendManage.createImageLegend(X._array, 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(X._array, xdata._array, ydata._array, 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()
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
igraphic.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(igraphic, zorder=zorder)
|
||
self.set_draw_extent(igraphic.getExtent())
|
||
gridline = self._axes.getGridLine()
|
||
gridline.setTop(True)
|
||
|
||
if ls is None:
|
||
return igraphic
|
||
else:
|
||
return ls
|
||
|
||
def pcolor(self, *args, **kwargs):
|
||
"""
|
||
Draw a pseudo color 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)
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
visible = kwargs.pop('visible', True)
|
||
if visible:
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
self.set_draw_extent(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)
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
visible = kwargs.pop('visible', True)
|
||
if visible:
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
self.set_draw_extent(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 in 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)
|
||
|
||
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('curve', 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)
|
||
|
||
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)
|
||
|
||
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 fill(self, x, y, color=None, **kwargs):
|
||
"""
|
||
Plot filled polygons.
|
||
|
||
- To plot one region, specify x and y as vectors.
|
||
- To plot multiple regions, specify x and y as matrices where each column corresponds to a polygon.
|
||
|
||
:param x: (*array_like*) X coordinates for each vertex.
|
||
:param y: (*array_like*) Y coordinates for each vertex.
|
||
:param color: (*Color*) Fill color.
|
||
|
||
:return: Filled polygons
|
||
"""
|
||
if color is not None:
|
||
kwargs['facecolor'] = color
|
||
lbreak, isunique = plotutil.getlegendbreak('polygon', **kwargs)
|
||
|
||
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)
|
||
|
||
return graphics
|
||
|
||
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)
|
||
|
||
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)
|
||
|
||
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)
|
||
|
||
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)
|
||
|
||
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)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
for graphic in graphics:
|
||
self.add_graphic(graphic)
|
||
|
||
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)
|
||
self._axes.setClip(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, **kwargs):
|
||
"""
|
||
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.getmarkerplotstyle(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)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
self.add_graphic(graphics)
|
||
|
||
return graphics
|
||
|
||
def violinplot(self, dataset, positions=None, widths=0.5, boxwidth=0.01, boxprops=None,
|
||
whiskerprops=None, **kwargs):
|
||
"""
|
||
Make a violin plot.
|
||
|
||
:param dataset: (*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 = 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. Default is 10.
|
||
: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)
|
||
graphics = GraphicFactory.createBarbs(x, y, u, v, cdata, ls, isuv)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
graphics.setAntiAlias(antialias)
|
||
|
||
if not xaxistype is None:
|
||
self.set_xaxis_type(xaxistype)
|
||
self._axes.updateDrawExtent()
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(graphics, zorder=zorder)
|
||
|
||
return graphics
|
||
|
||
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()
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
igraphic.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(igraphic, zorder=zorder)
|
||
|
||
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 2D 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*) 2D 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]
|
||
|
||
if not kwargs.has_key('headwidth'):
|
||
kwargs['headwidth'] = 8
|
||
if not kwargs.has_key('overhang'):
|
||
kwargs['overhang'] = 0.5
|
||
|
||
cdata = kwargs.pop('cdata', None)
|
||
if cdata is None:
|
||
alb, isunique = plotutil.getlegendbreak('line', **kwargs)
|
||
alb = plotutil.line2stream(alb, **kwargs)
|
||
igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array,
|
||
density, alb, isuv)
|
||
else:
|
||
if isinstance(cdata, (list, tuple)):
|
||
cdata = np.array(cdata)
|
||
levels = kwargs.pop('levels', None)
|
||
if levels is None:
|
||
cnum = kwargs.pop('cnum', None)
|
||
if cnum is None:
|
||
ls = plotutil.getlegendscheme([], cdata.min(), cdata.max(), **kwargs)
|
||
else:
|
||
ls = plotutil.getlegendscheme([cnum], cdata.min(), cdata.max(), **kwargs)
|
||
else:
|
||
ls = plotutil.getlegendscheme([levels], cdata.min(), cdata.max(), **kwargs)
|
||
ls = plotutil.setlegendscheme_line(ls, **kwargs)
|
||
for i in range(ls.getBreakNum()):
|
||
lb = plotutil.line2stream(ls.getLegendBreak(i), **kwargs)
|
||
ls.setLegendBreak(i, lb)
|
||
|
||
igraphic = GraphicFactory.createStreamlines(x._array, y._array, u._array, v._array,
|
||
cdata._array, density, ls, isuv)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
igraphic.setAntiAlias(antialias)
|
||
|
||
zorder = kwargs.pop('zorder', None)
|
||
self.add_graphic(igraphic, zorder=zorder)
|
||
|
||
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*) Legend orientation: ``vertical`` or ``horizontal``.
|
||
:param loc: (*string*) The location of the legend, including: 'upper right', 'upper left',
|
||
'lower left', 'lower right', 'right', 'center 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. Default is `3`.
|
||
:param titlespace: (*float*) Title space. Default is `5`.
|
||
: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)
|
||
titlespace = kwargs.pop('titlespace', None)
|
||
if titlespace is not None:
|
||
clegend.setTitleSpace(titlespace)
|
||
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)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
clegend.setAntiAlias(antialias)
|
||
|
||
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. If ``False`` the extensions will be triangular (the default).
|
||
: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 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, ImageGraphic):
|
||
ls = mappable.getLegendScheme()
|
||
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', None)
|
||
if extend is not None:
|
||
legend.setExtendType(extend)
|
||
extendrect = kwargs.pop('extendrect', True)
|
||
legend.setExtendRect(extendrect)
|
||
extendfrac = kwargs.pop('extendfrac', None)
|
||
if extendfrac is not None:
|
||
if extendfrac == 'auto':
|
||
efrac = ExtendFraction.AUTO
|
||
else:
|
||
efrac = ExtendFraction.LENGTH
|
||
efrac.fraction = extendfrac
|
||
legend.setExtendFraction(efrac)
|
||
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)
|
||
|
||
antialias = kwargs.pop('antialias', None)
|
||
if antialias is not None:
|
||
legend.setAntiAlias(antialias)
|
||
|
||
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)
|
||
#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
|