mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
1145 lines
36 KiB
Python
1145 lines
36 KiB
Python
# -----------------------------------------------------
|
|
# Author: Yaqiang Wang
|
|
# Date: 2017-7-27
|
|
# Purpose: MeteoInfo plotutil module in plotlib package
|
|
# Note: Jython
|
|
# -----------------------------------------------------
|
|
|
|
import os
|
|
import datetime
|
|
|
|
from org.meteoinfo.geometry.legend import LineStyles, HatchStyle, ColorBreak, PointBreak, PolylineBreak, \
|
|
PolygonBreak, ArrowBreak, ArrowLineBreak, ArrowPolygonBreak, StreamlineBreak, \
|
|
PointStyle, MarkerType, LegendScheme
|
|
from org.meteoinfo.geo.legend import LegendManage
|
|
from org.meteoinfo.common.colors import ColorUtil, ColorMap
|
|
from org.meteoinfo.geometry.shape import ShapeTypes
|
|
from org.meteoinfo.chart import ChartText
|
|
|
|
from java.awt import Color, Font
|
|
|
|
from mipylib.numeric.core import NDArray, DimArray
|
|
import mipylib.numeric as np
|
|
import mipylib.miutil as miutil
|
|
import mipylib.migl as migl
|
|
|
|
|
|
def getplotdata(data):
|
|
if isinstance(data, NDArray):
|
|
if data.dtype == np.dtype.date:
|
|
return data.astype('double')._array
|
|
return data.asarray()
|
|
elif isinstance(data, (list, tuple)):
|
|
if isinstance(data[0], datetime.datetime):
|
|
dd = []
|
|
for d in data:
|
|
v = miutil.date2num(d)
|
|
dd.append(v)
|
|
return np.array(dd)._array
|
|
else:
|
|
return np.array(data)._array
|
|
else:
|
|
return np.array([data])._array
|
|
|
|
|
|
def getfont(fontdic, **kwargs):
|
|
basefont = kwargs.pop('basefont', None)
|
|
if basefont is None:
|
|
name = 'Arial'
|
|
size = 14
|
|
bold = False
|
|
italic = False
|
|
else:
|
|
name = basefont.getName()
|
|
size = basefont.getSize()
|
|
bold = basefont.isBold()
|
|
italic = basefont.isItalic()
|
|
name = fontdic.pop('name', name)
|
|
size = fontdic.pop('size', size)
|
|
bold = fontdic.pop('bold', bold)
|
|
italic = fontdic.pop('italic', italic)
|
|
if bold:
|
|
if italic:
|
|
font = Font(name, Font.BOLD | Font.ITALIC, size)
|
|
else:
|
|
font = Font(name, Font.BOLD, size)
|
|
else:
|
|
if italic:
|
|
font = Font(name, Font.ITALIC, size)
|
|
else:
|
|
font = Font(name, Font.PLAIN, size)
|
|
return font
|
|
|
|
|
|
def getfont_1(**kwargs):
|
|
fontname = kwargs.pop('fontname', 'Arial')
|
|
fontsize = kwargs.pop('fontsize', 14)
|
|
bold = kwargs.pop('bold', False)
|
|
if bold:
|
|
font = Font(fontname, Font.BOLD, fontsize)
|
|
else:
|
|
font = Font(fontname, Font.PLAIN, fontsize)
|
|
return font
|
|
|
|
|
|
def getcolor(style, alpha=None):
|
|
if style is None:
|
|
return None
|
|
|
|
if isinstance(style, Color):
|
|
c = style
|
|
if alpha is not None:
|
|
alpha = int(alpha * 255)
|
|
c = Color(c.getRed(), c.getGreen(), c.getBlue(), alpha)
|
|
return c
|
|
|
|
c = Color.black
|
|
if isinstance(style, str):
|
|
if style == 'red' or style == 'r':
|
|
c = Color.red
|
|
elif style == 'black' or style == 'k':
|
|
c = Color.black
|
|
elif style == 'blue' or style == 'b':
|
|
c = Color.blue
|
|
elif style == 'green' or style == 'g':
|
|
c = Color.green
|
|
elif style == 'white' or style == 'w':
|
|
c = Color.white
|
|
elif style == 'yellow' or style == 'y':
|
|
c = Color.yellow
|
|
elif style == 'gray':
|
|
c = Color.gray
|
|
elif style == 'lightgray':
|
|
c = Color.lightGray
|
|
elif style == 'cyan' or style == 'c':
|
|
c = Color.cyan
|
|
elif style == 'magenta' or style == 'm':
|
|
c = Color.magenta
|
|
elif style == 'pink' or style == 'p':
|
|
c = Color.pink
|
|
elif style == 'tan':
|
|
c = Color(210, 180, 140)
|
|
elif style == 'lime':
|
|
c = Color(124, 252, 0)
|
|
else:
|
|
try:
|
|
c = ColorUtil.parseToColor(style)
|
|
except:
|
|
c = None
|
|
print('Not a valid color: {}'.format(style))
|
|
return c
|
|
elif isinstance(style, (NDArray, tuple, list)):
|
|
if len(style) == 3:
|
|
c = Color(style[0], style[1], style[2])
|
|
else:
|
|
c = Color(style[0], style[1], style[2], style[3])
|
|
|
|
if alpha is not None:
|
|
alpha = int(alpha * 255)
|
|
c = Color(c.getRed(), c.getGreen(), c.getBlue(), alpha)
|
|
|
|
return c
|
|
|
|
|
|
def getcolor_style(style):
|
|
c = Color.black
|
|
rr = None
|
|
if 'r' in style:
|
|
c = Color.red
|
|
rr = 'r'
|
|
elif 'k' in style:
|
|
c = Color.black
|
|
rr = 'k'
|
|
elif 'b' in style:
|
|
c = Color.blue
|
|
rr = 'b'
|
|
elif 'g' in style:
|
|
c = Color.green
|
|
rr = 'g'
|
|
elif 'w' in style:
|
|
c = Color.white
|
|
rr = 'w'
|
|
elif 'c' in style:
|
|
c = Color.cyan
|
|
rr = 'c'
|
|
elif 'm' in style:
|
|
c = Color.magenta
|
|
rr = 'm'
|
|
elif 'y' in style:
|
|
c = Color.yellow
|
|
rr = 'y'
|
|
elif 'p' in style:
|
|
c = Color.pink
|
|
rr = 'p'
|
|
|
|
if not rr is None:
|
|
style = style.replace(rr, '')
|
|
return c, style
|
|
|
|
|
|
def getcolors(cs, alpha=None):
|
|
colors = []
|
|
if isinstance(cs, (tuple, list, NDArray)):
|
|
if isinstance(cs[0], int):
|
|
colors.append(getcolor(cs, alpha))
|
|
else:
|
|
if isinstance(alpha, (tuple, list)):
|
|
for c, a in zip(cs, alpha):
|
|
colors.append(getcolor(c, a))
|
|
else:
|
|
for c in cs:
|
|
colors.append(getcolor(c, alpha))
|
|
else:
|
|
colors.append(getcolor(cs, alpha))
|
|
return colors
|
|
|
|
|
|
def getcolormap(**kwargs):
|
|
colors = kwargs.pop('colors', None)
|
|
is_single = False
|
|
reverse = False
|
|
if colors is None:
|
|
colors = kwargs.pop('color', None)
|
|
is_single = True
|
|
|
|
alpha = kwargs.pop('alpha', None)
|
|
if not colors is None:
|
|
if is_single or isinstance(colors, str):
|
|
c = getcolor(colors, alpha)
|
|
cmap = ColorMap(c)
|
|
else:
|
|
cs = []
|
|
for cc in colors:
|
|
c = getcolor(cc, alpha)
|
|
cs.append(c)
|
|
cmap = ColorMap(cs)
|
|
else:
|
|
cmapstr = kwargs.pop('cmap', 'parula')
|
|
if len(cmapstr) > 2 and cmapstr[-2:] == '_r':
|
|
cmapstr = cmapstr[:-2]
|
|
reverse = True
|
|
fn = cmapstr + '.rgb'
|
|
fn = os.path.join(migl.get_cmap_folder(), fn)
|
|
if not os.path.exists(fn):
|
|
raise IOError('cmap file not exists: %s' % fn)
|
|
|
|
if alpha is None:
|
|
cmap = ColorUtil.loadColorMap(fn)
|
|
else:
|
|
alpha = (int)(alpha * 255)
|
|
cmap = ColorUtil.loadColorMap(fn, alpha)
|
|
reverse = kwargs.pop('cmapreverse', reverse)
|
|
if reverse:
|
|
cmap.reverse()
|
|
return cmap
|
|
|
|
|
|
def makecolors(n, cmap='matlab_jet', reverse=False, alpha=None, start=None, stop=None):
|
|
"""
|
|
Make colors.
|
|
|
|
:param n: (*int*) Colors number.
|
|
:param cmap: (*string*) Color map name. Default is ``matlab_jet``.
|
|
:param reverse: (*boolean*) Reverse the colors or not. Default is ``False``.
|
|
:param alpha: (*float*) Alpha value (0 - 1) of the colors. Default is ``None``.
|
|
:param start: (*int*) Start color index. Default is ``None``.
|
|
:param stop: (*int*) Stop color index. Default is ``None``.
|
|
|
|
:returns: (*list*) Created colors.
|
|
"""
|
|
if isinstance(n, list):
|
|
cols = getcolors(n, alpha)
|
|
else:
|
|
# ocmap = ColorUtil.getColorMap(cmap)
|
|
ocmap = getcolormap(cmap=cmap)
|
|
if reverse:
|
|
ocmap.reverse()
|
|
if start is None and stop is None:
|
|
if alpha is None:
|
|
cols = ocmap.getColorList(n)
|
|
else:
|
|
alpha = (int)(alpha * 255)
|
|
cols = ocmap.getColorListAlpha(n, alpha)
|
|
else:
|
|
if start is None:
|
|
start = 0
|
|
if stop is None:
|
|
stop = ocmap.getColorCount() - 1
|
|
if alpha is None:
|
|
cols = ocmap.getColorList(n, start, stop)
|
|
else:
|
|
alpha = (int)(alpha * 255)
|
|
cols = ocmap.getColorListAlpha(n, alpha, start, stop)
|
|
return list(cols)
|
|
|
|
|
|
def getpointstyle(style):
|
|
if style is None:
|
|
return None
|
|
|
|
pointStyle = None
|
|
if 'do' in style:
|
|
pointStyle = PointStyle.DOUBLE_CIRCLE
|
|
elif 'os' in style:
|
|
pointStyle = PointStyle.CIRCLE_STAR
|
|
elif 'o' in style:
|
|
pointStyle = PointStyle.CIRCLE
|
|
elif '.' in style:
|
|
pointStyle = PointStyle.CIRCLE
|
|
elif 'D' in style:
|
|
pointStyle = PointStyle.DIAMOND
|
|
elif '+' in style:
|
|
pointStyle = PointStyle.PLUS
|
|
elif 'm' in style:
|
|
pointStyle = PointStyle.MINUS
|
|
elif 's' in style:
|
|
pointStyle = PointStyle.SQUARE
|
|
elif 'S' in style:
|
|
pointStyle = PointStyle.STAR
|
|
elif '*' in style:
|
|
pointStyle = PointStyle.STAR_LINES
|
|
elif '^' in style:
|
|
pointStyle = PointStyle.UP_TRIANGLE
|
|
elif 'x' in style:
|
|
pointStyle = PointStyle.X_CROSS
|
|
elif 'p' in style:
|
|
pointStyle = PointStyle.PENTAGON
|
|
|
|
return pointStyle
|
|
|
|
|
|
def getlinestyle(style):
|
|
if style is None:
|
|
return None
|
|
|
|
lineStyle = None
|
|
if style[0].isalpha():
|
|
style = style.upper()
|
|
lineStyle = LineStyles.valueOf(style)
|
|
else:
|
|
if '--' in style:
|
|
lineStyle = LineStyles.DASH
|
|
elif ':' in style:
|
|
lineStyle = LineStyles.DOT
|
|
elif '-.' in style:
|
|
lineStyle = LineStyles.DASH_DOT
|
|
elif '-' in style:
|
|
lineStyle = LineStyles.SOLID
|
|
|
|
return lineStyle
|
|
|
|
|
|
def getlinestyle_1(style):
|
|
if style is None:
|
|
return None
|
|
|
|
lineStyle = None
|
|
rr = None
|
|
if '--' in style:
|
|
lineStyle = LineStyles.DASH
|
|
rr = '--'
|
|
elif ':' in style:
|
|
lineStyle = LineStyles.DOT
|
|
rr = ':'
|
|
elif '-.' in style:
|
|
lineStyle = LineStyles.DASH_DOT
|
|
rr = '-.'
|
|
elif '-' in style:
|
|
lineStyle = LineStyles.SOLID
|
|
rr = '-'
|
|
|
|
if not rr is None:
|
|
style = style.replace(rr, '')
|
|
return lineStyle, style
|
|
|
|
|
|
def gethatch(h):
|
|
if h is None:
|
|
return h
|
|
else:
|
|
return HatchStyle.getStyle(h)
|
|
|
|
|
|
def getplotstyle(style, caption, **kwargs):
|
|
linewidth = kwargs.pop('linewidth', 1.0)
|
|
if style is None:
|
|
color = kwargs.pop('color', 'red')
|
|
c = getcolor(color)
|
|
else:
|
|
c, style = getcolor_style(style)
|
|
if kwargs.has_key('color'):
|
|
c = getcolor(kwargs.pop('color'))
|
|
lineStyle, style = getlinestyle_1(style)
|
|
pointStyle = getpointstyle(style)
|
|
if not pointStyle is None:
|
|
fill = kwargs.pop('fill', True)
|
|
if lineStyle is None:
|
|
pb = PointBreak()
|
|
pb.setCaption(caption)
|
|
if '.' in style:
|
|
pb.setSize(4)
|
|
pb.setDrawOutline(False)
|
|
else:
|
|
pb.setSize(8)
|
|
pb.setStyle(pointStyle)
|
|
pb.setDrawFill(fill)
|
|
if not c is None:
|
|
pb.setColor(c)
|
|
edgecolor = kwargs.pop('edgecolor', pb.getColor())
|
|
edgecolor = getcolor(edgecolor)
|
|
pb.setOutlineColor(edgecolor)
|
|
setpointlegendbreak(pb, **kwargs)
|
|
return pb
|
|
else:
|
|
plb = PolylineBreak()
|
|
plb.setCaption(caption)
|
|
plb.setWidth(linewidth)
|
|
plb.setStyle(lineStyle)
|
|
plb.setDrawSymbol(True)
|
|
plb.setSymbolStyle(pointStyle)
|
|
plb.setFillSymbol(fill)
|
|
interval = kwargs.pop('markerinterval', 1)
|
|
plb.setSymbolInterval(interval)
|
|
if not c is None:
|
|
plb.setColor(c)
|
|
markersize = kwargs.pop('markersize', None)
|
|
if not markersize is None:
|
|
plb.setSymbolSize(markersize)
|
|
markercolor = kwargs.pop('markeredgecolor', plb.getColor())
|
|
markercolor = getcolor(markercolor)
|
|
plb.setSymbolColor(markercolor)
|
|
markerfillcolor = kwargs.pop('markerfacecolor', markercolor)
|
|
markerfillcolor = getcolor(markerfillcolor)
|
|
plb.setSymbolFillColor(markerfillcolor)
|
|
plb.setFillSymbol(not markerfillcolor is None)
|
|
return plb
|
|
else:
|
|
plb = PolylineBreak()
|
|
plb.setCaption(caption)
|
|
plb.setWidth(linewidth)
|
|
if not c is None:
|
|
plb.setColor(c)
|
|
if not lineStyle is None:
|
|
plb.setStyle(lineStyle)
|
|
return plb
|
|
|
|
|
|
def getlegendbreak(geometry, **kwargs):
|
|
fill = True
|
|
color = None
|
|
if kwargs.has_key('color'):
|
|
color = kwargs.pop('color')
|
|
if color is None:
|
|
fill = False
|
|
else:
|
|
color = getcolor(color)
|
|
else:
|
|
if kwargs.has_key('facecolor'):
|
|
color = kwargs.pop('facecolor')
|
|
if color is None:
|
|
fill = False
|
|
else:
|
|
color = getcolor(color)
|
|
|
|
if geometry == 'point':
|
|
lb = PointBreak()
|
|
marker = kwargs.pop('marker', 'o')
|
|
if marker == 'image':
|
|
imagepath = kwargs.pop('imagepath', None)
|
|
if not imagepath is None:
|
|
lb.setMarkerType(MarkerType.IMAGE)
|
|
lb.setImagePath(imagepath)
|
|
elif marker == 'font':
|
|
fontname = kwargs.pop('fontname', 'Weather')
|
|
lb.setMarkerType(MarkerType.CHARACTER)
|
|
lb.setFontName(fontname)
|
|
charindex = kwargs.pop('charindex', 0)
|
|
lb.setCharIndex(charindex)
|
|
else:
|
|
pstyle = getpointstyle(marker)
|
|
lb.setStyle(pstyle)
|
|
if not color is None:
|
|
lb.setColor(color)
|
|
size = kwargs.pop('size', 6)
|
|
lb.setSize(size)
|
|
edge = True
|
|
edgecolor = None
|
|
if kwargs.has_key('edgecolor'):
|
|
edgecolor = kwargs.pop('edgecolor')
|
|
if edgecolor is None:
|
|
edge = False
|
|
else:
|
|
edgecolor = getcolor(edgecolor)
|
|
if not edgecolor is None:
|
|
lb.setOutlineColor(edgecolor)
|
|
linewith = kwargs.pop('linewidth', None)
|
|
edgesize = kwargs.pop('edgesize', linewith)
|
|
if not edgesize is None:
|
|
lb.setOutlineSize(edgesize)
|
|
fill = kwargs.pop('fill', fill)
|
|
lb.setDrawFill(fill)
|
|
edge = kwargs.pop('edge', edge)
|
|
lb.setDrawOutline(edge)
|
|
elif geometry == 'line':
|
|
lb = PolylineBreak()
|
|
if not color is None:
|
|
lb.setColor(color)
|
|
size = kwargs.pop('size', 1.0)
|
|
size = kwargs.pop('linewidth', size)
|
|
lb.setWidth(size)
|
|
lsobj = kwargs.pop('linestyle', '-')
|
|
linestyle = getlinestyle(lsobj)
|
|
lb.setStyle(linestyle)
|
|
marker = kwargs.pop('marker', None)
|
|
if not marker is None:
|
|
pstyle = getpointstyle(marker)
|
|
lb.setDrawSymbol(True)
|
|
lb.setSymbolStyle(pstyle)
|
|
markersize = kwargs.pop('markersize', None)
|
|
if not markersize is None:
|
|
lb.setSymbolSize(markersize)
|
|
markercolor = kwargs.pop('markeredgecolor', lb.getColor())
|
|
markercolor = getcolor(markercolor)
|
|
lb.setSymbolColor(markercolor)
|
|
fillcolor = kwargs.pop('markerfacecolor', lb.getColor())
|
|
if not fillcolor is None:
|
|
lb.setFillSymbol(True)
|
|
lb.setSymbolFillColor(getcolor(fillcolor))
|
|
else:
|
|
lb.setSymbolFillColor(markercolor)
|
|
interval = kwargs.pop('markerinterval', 1)
|
|
lb.setSymbolInterval(interval)
|
|
elif geometry == 'polygon':
|
|
lb = PolygonBreak()
|
|
edge = True
|
|
edgecolor = None
|
|
if kwargs.has_key('edgecolor'):
|
|
edgecolor = kwargs.pop('edgecolor')
|
|
if edgecolor is None:
|
|
edge = False
|
|
else:
|
|
edgecolor = getcolor(edgecolor)
|
|
if not edgecolor is None:
|
|
lb.setOutlineColor(edgecolor)
|
|
fill = kwargs.pop('fill', fill)
|
|
lb.setDrawFill(fill)
|
|
edge = kwargs.pop('edge', edge)
|
|
lb.setDrawOutline(edge)
|
|
size = kwargs.pop('size', None)
|
|
size = kwargs.pop('linewidth', size)
|
|
size = kwargs.pop('edgesize', size)
|
|
if not size is None:
|
|
lb.setOutlineSize(size)
|
|
hatch = kwargs.pop('hatch', None)
|
|
hatch = gethatch(hatch)
|
|
hatchsize = kwargs.pop('hatchsize', None)
|
|
hatchlinewidth = kwargs.pop('hatchlinewidth', None)
|
|
bgcolor = kwargs.pop('bgcolor', None)
|
|
bgcolor = getcolor(bgcolor)
|
|
if not hatch is None:
|
|
lb.setStyle(hatch)
|
|
if not bgcolor is None:
|
|
lb.setBackColor(bgcolor)
|
|
if not hatchsize is None:
|
|
lb.setStyleSize(hatchsize)
|
|
if not hatchlinewidth is None:
|
|
lb.setStyleLineWidth(hatchlinewidth)
|
|
else:
|
|
lb = ColorBreak()
|
|
caption = kwargs.pop('caption', None)
|
|
if not caption is None:
|
|
lb.setCaption(caption)
|
|
if not color is None:
|
|
lb.setColor(color)
|
|
alpha = kwargs.pop('alpha', None)
|
|
if not alpha is None:
|
|
lb.setColor(getcolor(lb.getColor(), alpha))
|
|
value = kwargs.pop('value', None)
|
|
isunique = True
|
|
if not value is None:
|
|
if isinstance(value, (tuple, list)):
|
|
lb.setStartValue(value[0])
|
|
lb.setEndValue(value[1])
|
|
isunique = False
|
|
else:
|
|
lb.setStartValue(value)
|
|
lb.setEndValue(value)
|
|
return lb, isunique
|
|
|
|
|
|
def getlegendscheme(args, min, max, **kwargs):
|
|
ls = kwargs.pop('symbolspec', None)
|
|
if ls is None:
|
|
cmap = getcolormap(**kwargs)
|
|
if len(args) > 0:
|
|
level_arg = args[0]
|
|
if isinstance(level_arg, int):
|
|
cn = level_arg
|
|
ls = LegendManage.createLegendScheme(min, max, cn, cmap)
|
|
else:
|
|
if isinstance(level_arg, NDArray):
|
|
level_arg = level_arg.aslist()
|
|
ls = LegendManage.createLegendScheme(min, max, level_arg, cmap)
|
|
else:
|
|
ls = LegendManage.createLegendScheme(min, max, cmap)
|
|
# ecobj = kwargs.pop('edgecolor', None)
|
|
# if not ecobj is None:
|
|
# edgecolor = getcolor(ecobj)
|
|
# ls = ls.convertTo(ShapeTypes.POLYGON)
|
|
# for lb in ls.getLegendBreaks():
|
|
# lb.setDrawOutline(True)
|
|
# lb.setOutlineColor(edgecolor)
|
|
return ls
|
|
|
|
|
|
def setlegendscheme(ls, **kwargs):
|
|
st = ls.getShapeType()
|
|
if st == ShapeTypes.POINT:
|
|
setlegendscheme_point(ls, **kwargs)
|
|
elif st == ShapeTypes.POLYLINE:
|
|
setlegendscheme_line(ls, **kwargs)
|
|
elif st == ShapeTypes.POLYGON:
|
|
setlegendscheme_polygon(ls, **kwargs)
|
|
else:
|
|
setlegendscheme_image(ls, **kwargs)
|
|
|
|
|
|
def setlegendscheme_image(ls, **kwargs):
|
|
cobj = kwargs.pop('color', None)
|
|
alpha = kwargs.pop('alpha', None)
|
|
for lb in ls.getLegendBreaks():
|
|
if not cobj is None:
|
|
color = getcolor(cobj)
|
|
lb.setColor(color)
|
|
if not alpha is None:
|
|
c = lb.getColor()
|
|
c = getcolor(c, alpha)
|
|
lb.setColor(c)
|
|
|
|
return ls
|
|
|
|
|
|
def setlegendscheme_point(ls, **kwargs):
|
|
ls = ls.convertTo(ShapeTypes.POINT)
|
|
sizes = kwargs.get('size', None)
|
|
colors = kwargs.get('colors', None)
|
|
edgecolors = kwargs.get('edgecolors', None)
|
|
marker = kwargs.get('marker', None)
|
|
i = 0
|
|
for lb in ls.getLegendBreaks():
|
|
if isinstance(sizes, (list, tuple, NDArray)):
|
|
kwargs['size'] = sizes[i]
|
|
if isinstance(colors, (list, tuple, NDArray)):
|
|
kwargs['color'] = colors[i]
|
|
if isinstance(edgecolors, (list, tuple, NDArray)):
|
|
kwargs['edgecolor'] = edgecolors[i]
|
|
if isinstance(marker, (list, tuple, NDArray)):
|
|
kwargs['marker'] = marker[i]
|
|
setpointlegendbreak(lb, **kwargs)
|
|
i += 1
|
|
|
|
return ls
|
|
|
|
|
|
def setlegendscheme_arrow(ls, **kwargs):
|
|
"""
|
|
Set legend scheme as arrow breaks.
|
|
|
|
:param ls: (*LegendScheme') Input legend scheme.
|
|
|
|
:returns: (*LegendScheme*) Result legend scheme.
|
|
"""
|
|
ls = ls.convertTo(ShapeTypes.POINT)
|
|
sizes = kwargs.get('size', None)
|
|
colors = kwargs.get('colors', None)
|
|
marker = kwargs.get('marker', None)
|
|
for i in range(ls.getBreakNum()):
|
|
lb = ls.getLegendBreak(i)
|
|
if isinstance(sizes, (list, tuple, NDArray)):
|
|
kwargs['size'] = sizes[i]
|
|
if isinstance(colors, (list, tuple, NDArray)):
|
|
kwargs['color'] = colors[i]
|
|
if isinstance(marker, (list, tuple, NDArray)):
|
|
kwargs['marker'] = marker[i]
|
|
if not kwargs.has_key('edgecolor'):
|
|
kwargs['edgecolor'] = None
|
|
setpointlegendbreak(lb, **kwargs)
|
|
lb = point2arrow(lb, **kwargs)
|
|
ls.setLegendBreak(i, lb)
|
|
|
|
return ls
|
|
|
|
|
|
def point2arrow(pb, **kwargs):
|
|
"""
|
|
Convert point break to arrow break.
|
|
|
|
:param pb: (*PointBreak*) Point break.
|
|
:param width: (*float*) Arrow line width.
|
|
:param headwidth: (*float*) Arrow head width. Default is ``width*5``.
|
|
:param headlength: (*float*) Arrow head length.
|
|
:param overhang: (*float*) fraction that the arrow is swept back (0 overhang means
|
|
triangular shape). Can be negative or greater than one.
|
|
|
|
:returns: (*ArrowBreak*) Arrow break.
|
|
"""
|
|
arrowbreak = ArrowBreak(pb)
|
|
width = kwargs.pop('width', 1.)
|
|
arrowbreak.initWidth(width)
|
|
headwidth = kwargs.pop('headwidth', None)
|
|
if not headwidth is None:
|
|
arrowbreak.setHeadWidth(headwidth)
|
|
headlength = kwargs.pop('headlength', None)
|
|
if not headlength is None:
|
|
arrowbreak.setHeadLength(headlength)
|
|
overhang = kwargs.pop('overhang', None)
|
|
if not overhang is None:
|
|
arrowbreak.setOverhang(overhang)
|
|
|
|
return arrowbreak
|
|
|
|
|
|
def line2arrow(lb, **kwargs):
|
|
"""
|
|
Convert linestring break to arrow line break.
|
|
|
|
:param lb: (*PolylineBreak*) Linestring break.
|
|
:param headwidth: (*float*) Arrow head width. Default is ``width*5``.
|
|
:param headlength: (*float*) Arrow head length.
|
|
:param overhang: (*float*) fraction that the arrow is swept back (0 overhang means
|
|
triangular shape). Can be negative or greater than one.
|
|
:param fillcolor: (*Color*) Arrow fill color.
|
|
:param edgecolor: (*Color*) Arrow edge color.
|
|
|
|
:returns: (*ArrowLineBreak*) Arrow line break.
|
|
"""
|
|
albreak = ArrowLineBreak(lb)
|
|
headwidth = kwargs.pop('headwidth', lb.getWidth() * 5.)
|
|
albreak.setArrowHeadWidth(headwidth)
|
|
headlength = kwargs.pop('headlength', headwidth * 1.5)
|
|
albreak.setArrowHeadLength(headlength)
|
|
overhang = kwargs.pop('overhang', None)
|
|
if not overhang is None:
|
|
albreak.setArrowOverhang(overhang)
|
|
if kwargs.has_key('fillcolor'):
|
|
fillcolor = kwargs.pop('fillcolor')
|
|
albreak.setArrowFillColor(getcolor(fillcolor))
|
|
if kwargs.has_key('edgecolor'):
|
|
edgecolor = kwargs.pop('edgecolor')
|
|
albreak.setArrowOutlineColor(getcolor(edgecolor))
|
|
|
|
return albreak
|
|
|
|
|
|
def line2stream(lb, **kwargs):
|
|
"""
|
|
Convert linestring break to streamline break.
|
|
|
|
:param lb: (*PolylineBreak*) Linestring break.
|
|
:param headwidth: (*float*) Arrow head width. Default is ``width*5``.
|
|
:param headlength: (*float*) Arrow head length.
|
|
:param overhang: (*float*) fraction that the arrow is swept back (0 overhang means
|
|
triangular shape). Can be negative or greater than one.
|
|
:param fillcolor: (*Color*) Arrow fill color.
|
|
:param edgecolor: (*Color*) Arrow edge color.
|
|
:param interval: (*int*) Arrow interval.
|
|
|
|
:returns: (*StreamineBreak*) Stream line break.
|
|
"""
|
|
albreak = StreamlineBreak(lb)
|
|
headwidth = lb.getWidth() * 5.
|
|
if kwargs.has_key('headwidth'):
|
|
headwidth = kwargs['headwidth']
|
|
albreak.setArrowHeadWidth(headwidth)
|
|
headlength = headwidth * 1.5
|
|
if kwargs.has_key('headlength'):
|
|
headlength = kwargs['headlength']
|
|
albreak.setArrowHeadLength(headlength)
|
|
overhang = None
|
|
if kwargs.has_key('overhang'):
|
|
overhang = kwargs['overhang']
|
|
if not overhang is None:
|
|
albreak.setArrowOverhang(overhang)
|
|
if kwargs.has_key('fillcolor'):
|
|
fillcolor = kwargs['fillcolor']
|
|
albreak.setArrowFillColor(getcolor(fillcolor))
|
|
if kwargs.has_key('edgecolor'):
|
|
edgecolor = kwargs['edgecolor']
|
|
albreak.setArrowOutlineColor(getcolor(edgecolor))
|
|
if kwargs.has_key('interval'):
|
|
interval = kwargs['interval']
|
|
albreak.setInterval(interval)
|
|
|
|
return albreak
|
|
|
|
|
|
def polygon2arrow(pb, **kwargs):
|
|
"""
|
|
Convert polygon break to arrow polygon break.
|
|
|
|
:param pb: (*PolygonBreak*) Polygon break.
|
|
:param width: (*float*) Arrow line width.
|
|
:param headwidth: (*float*) Arrow head width. Default is ``width*3``.
|
|
:param headlength: (*float*) Arrow head length.
|
|
:param overhang: (*float*) fraction that the arrow is swept back (0 overhang means
|
|
triangular shape). Can be negative or greater than one.
|
|
|
|
:returns: (*ArrowPolygonBreak*) Arrow polygon break.
|
|
"""
|
|
arrowbreak = ArrowPolygonBreak(pb)
|
|
width = kwargs.pop('width', 0.001)
|
|
arrowbreak.setWidth(width)
|
|
headwidth = kwargs.pop('headwidth', width * 3.)
|
|
arrowbreak.setHeadWidth(headwidth)
|
|
headlength = kwargs.pop('headlength', headwidth * 1.5)
|
|
arrowbreak.setHeadLength(headlength)
|
|
length_includes_head = kwargs.pop('length_includes_head', False)
|
|
arrowbreak.setLengthIncludesHead(length_includes_head)
|
|
overhang = kwargs.pop('overhang', None)
|
|
if not overhang is None:
|
|
arrowbreak.setOverhang(overhang)
|
|
|
|
return arrowbreak
|
|
|
|
|
|
def setlegendscheme_line(ls, **kwargs):
|
|
ls = ls.convertTo(ShapeTypes.POLYLINE)
|
|
size = kwargs.pop('size', None)
|
|
size = kwargs.pop('linewidth', size)
|
|
lsobj = kwargs.pop('linestyle', None)
|
|
linestyle = getlinestyle(lsobj)
|
|
cobj = kwargs.pop('color', None)
|
|
if cobj is None:
|
|
color = None
|
|
else:
|
|
color = getcolor(cobj)
|
|
for lb in ls.getLegendBreaks():
|
|
if not color is None:
|
|
lb.setColor(color)
|
|
if not linestyle is None:
|
|
lb.setStyle(linestyle)
|
|
if not size is None:
|
|
lb.setSize(size)
|
|
return ls
|
|
|
|
|
|
def setlegendscheme_polygon(ls, **kwargs):
|
|
ls = ls.convertTo(ShapeTypes.POLYGON)
|
|
fill = True
|
|
if 'facecolor' in kwargs.keys():
|
|
facecolor = kwargs['facecolor']
|
|
if facecolor is None:
|
|
fill = False
|
|
else:
|
|
facecolor = getcolor(facecolor)
|
|
else:
|
|
facecolor = None
|
|
edge = True
|
|
edgealpha = kwargs.pop('edgealpha', None)
|
|
if 'edgecolor' in kwargs.keys():
|
|
edgecolor = kwargs['edgecolor']
|
|
if edgecolor is None:
|
|
edge = False
|
|
else:
|
|
edgecolor = getcolor(edgecolor, edgealpha)
|
|
else:
|
|
edgecolor = None
|
|
edge = kwargs.pop('edge', edge)
|
|
edgesize = kwargs.pop('edgesize', None)
|
|
fill = kwargs.pop('fill', fill)
|
|
alpha = kwargs.pop('facealpha', None)
|
|
if alpha is None:
|
|
alpha = kwargs.pop('alpha', None)
|
|
hatch = kwargs.pop('hatch', None)
|
|
hatch = gethatch(hatch)
|
|
hatchsize = kwargs.pop('hatchsize', None)
|
|
hatchlinewidth = kwargs.pop('hatchlinewidth', None)
|
|
bgcolor = kwargs.pop('bgcolor', None)
|
|
bgcolor = getcolor(bgcolor)
|
|
for lb in ls.getLegendBreaks():
|
|
lb.setDrawFill(fill)
|
|
if facecolor is not None:
|
|
lb.setColor(facecolor)
|
|
if alpha is not None:
|
|
c = lb.getColor()
|
|
c = getcolor(c, alpha)
|
|
lb.setColor(c)
|
|
if edgesize is not None:
|
|
lb.setOutlineSize(edgesize)
|
|
lb.setDrawOutline(edge)
|
|
if edgecolor is None:
|
|
if edgealpha is not None:
|
|
edgecolor = lb.getOutlineColor()
|
|
edgecolor = getcolor(edgecolor, edgealpha)
|
|
lb.setOutlineColor(edgecolor)
|
|
else:
|
|
lb.setOutlineColor(edgecolor)
|
|
if hatch is not None:
|
|
lb.setStyle(hatch)
|
|
if bgcolor is not None:
|
|
lb.setBackColor(bgcolor)
|
|
if hatchsize is not None:
|
|
lb.setStyleSize(hatchsize)
|
|
if hatchlinewidth is not None:
|
|
lb.setStyleLineWidth(hatchlinewidth)
|
|
return ls
|
|
|
|
|
|
def setpointlegendbreak(lb, **kwargs):
|
|
if kwargs.has_key('marker'):
|
|
marker = kwargs['marker']
|
|
if marker == 'image':
|
|
if kwargs.has_key('imagepath'):
|
|
lb.setMarkerType(MarkerType.IMAGE)
|
|
lb.setImagePath(kwargs['imagepath'])
|
|
elif marker == 'font':
|
|
fontname = 'Weather'
|
|
if kwargs.has_key('fontname'):
|
|
fontname = kwargs['fontname']
|
|
lb.setMarkerType(MarkerType.CHARACTER)
|
|
lb.setFontName(fontname)
|
|
charindex = 0
|
|
if kwargs.has_key('charindex'):
|
|
charindex = kwargs['charindex']
|
|
lb.setCharIndex(charindex)
|
|
else:
|
|
pstyle = getpointstyle(marker)
|
|
lb.setStyle(pstyle)
|
|
color = lb.getColor()
|
|
if kwargs.has_key('color'):
|
|
color = kwargs['color']
|
|
elif kwargs.has_key('facecolor'):
|
|
color = kwargs['facecolor']
|
|
alpha = None
|
|
if kwargs.has_key('alpha'):
|
|
alpha = kwargs['alpha']
|
|
if color is None:
|
|
if alpha is None:
|
|
lb.setDrawFill(False)
|
|
else:
|
|
color = getcolor(lb.getColor(), alpha)
|
|
lb.setColor(color)
|
|
else:
|
|
color = getcolor(color, alpha)
|
|
lb.setColor(color)
|
|
if kwargs.has_key('size'):
|
|
size = kwargs['size']
|
|
lb.setSize(size)
|
|
if kwargs.has_key('markersize'):
|
|
size = kwargs['markersize']
|
|
lb.setSize(size)
|
|
if kwargs.has_key('edgecolor'):
|
|
ecobj = kwargs['edgecolor']
|
|
if ecobj is None:
|
|
lb.setDrawOutline(False)
|
|
else:
|
|
edgecolor = getcolor(ecobj)
|
|
lb.setOutlineColor(edgecolor)
|
|
if kwargs.has_key('fill'):
|
|
lb.setDrawFill(kwargs['fill'])
|
|
if kwargs.has_key('edge'):
|
|
lb.setDrawOutline(kwargs['edge'])
|
|
if kwargs.has_key('edgesize'):
|
|
lb.setOutlineSize(kwargs['edgesize'])
|
|
elif kwargs.has_key('linewidth'):
|
|
lb.setOutlineSize(kwargs['linewidth'])
|
|
|
|
|
|
def text(x, y, s, **kwargs):
|
|
"""
|
|
Add text to the axes. Add text in string *s* to axis at location *x* , *y* , data
|
|
coordinates.
|
|
|
|
:param x: (*float*) Data x coordinate.
|
|
:param y: (*float*) Data y coordinate.
|
|
:param s: (*string*) Text.
|
|
:param fontname: (*string*) Font name. Default is ``Arial`` .
|
|
:param fontsize: (*int*) Font size. Default is ``14`` .
|
|
:param bold: (*boolean*) Is bold font or not. Default is ``False`` .
|
|
:param color: (*color*) Tick label string color. Default is ``black`` .
|
|
:param coordinates=['axes'|'figure'|'data'|'inches']: (*string*) Coordinate system and units for
|
|
*X, Y*. 'axes' and 'figure' are normalized coordinate system with 0,0 in the lower left and
|
|
1,1 in the upper right, 'data' are the axes data coordinates (Default value); 'inches' is
|
|
position in the figure in inches, with 0,0 at the lower left corner.
|
|
|
|
:returns: (*ChartText*) text.
|
|
"""
|
|
fontname = kwargs.pop('fontname', None)
|
|
exfont = False
|
|
if fontname is None:
|
|
fontname = 'Arial'
|
|
else:
|
|
exfont = True
|
|
fontsize = kwargs.pop('fontsize', 14)
|
|
bold = kwargs.pop('bold', False)
|
|
color = kwargs.pop('color', 'black')
|
|
if bold:
|
|
font = Font(fontname, Font.BOLD, fontsize)
|
|
else:
|
|
font = Font(fontname, Font.PLAIN, fontsize)
|
|
c = getcolor(color)
|
|
text = ChartText(s, font)
|
|
text.setUseExternalFont(exfont)
|
|
text.setColor(c)
|
|
text.setX(x)
|
|
text.setY(y)
|
|
xshift = kwargs.pop('xshift', None)
|
|
if not xshift is None:
|
|
text.setXShift(xshift)
|
|
yshift = kwargs.pop('yshift', None)
|
|
if not yshift is None:
|
|
text.setYShift(yshift)
|
|
xalign = kwargs.pop('xalign', None)
|
|
if not xalign is None:
|
|
text.setXAlign(xalign)
|
|
yalign = kwargs.pop('yalign', None)
|
|
if not yalign is None:
|
|
text.setYAlign(yalign)
|
|
bbox = kwargs.pop('bbox', None)
|
|
if not bbox is None:
|
|
fill = bbox.pop('fill', None)
|
|
if not fill is None:
|
|
text.setFill(fill)
|
|
facecolor = bbox.pop('facecolor', None)
|
|
if not facecolor is None:
|
|
facecolor = getcolor(facecolor)
|
|
text.setFill(True)
|
|
text.setBackground(facecolor)
|
|
edge = bbox.pop('edge', None)
|
|
if not edge is None:
|
|
text.setDrawNeatline(edge)
|
|
edgecolor = bbox.pop('edgecolor', None)
|
|
if not edgecolor is None:
|
|
edgecolor = getcolor(edgecolor)
|
|
text.setNeatlineColor(edgecolor)
|
|
text.setDrawNeatline(True)
|
|
linewidth = bbox.pop('linewidth', None)
|
|
if not linewidth is None:
|
|
text.setNeatlineSize(linewidth)
|
|
text.setDrawNeatline(True)
|
|
gap = bbox.pop('gap', None)
|
|
if not gap is None:
|
|
text.setGap(gap)
|
|
rotation = kwargs.pop('rotation', None)
|
|
if not rotation is None:
|
|
text.setAngle(rotation)
|
|
coordinates = kwargs.pop('coordinates', 'data')
|
|
text.setCoordinates(coordinates)
|
|
return text
|
|
|
|
|
|
def makesymbolspec(geometry, *args, **kwargs):
|
|
"""
|
|
Make a legend.
|
|
|
|
:param geometry: (*string*) Geometry type. [point | line | polygon].
|
|
:param levels: (*array_like*) Value levels. Default is ``None``, not used.
|
|
:param colors: (*list*) Colors. Defaul is ``None``, not used.
|
|
:param field: (*string*) The field to be used in the legend.
|
|
|
|
:returns: Created legend.
|
|
"""
|
|
shapetype = ShapeTypes.IMAGE
|
|
if geometry == 'point':
|
|
shapetype = ShapeTypes.POINT
|
|
elif geometry == 'line':
|
|
shapetype = ShapeTypes.POLYLINE
|
|
elif geometry == 'polygon':
|
|
shapetype = ShapeTypes.POLYGON
|
|
|
|
levels = kwargs.pop('levels', None)
|
|
cols = kwargs.pop('colors', None)
|
|
field = kwargs.pop('field', '')
|
|
if not levels is None and not cols is None:
|
|
if isinstance(levels, NDArray):
|
|
levels = levels.aslist()
|
|
colors = []
|
|
for cobj in cols:
|
|
colors.append(getcolor(cobj))
|
|
ls = LegendManage.createLegendScheme(shapetype, levels, colors)
|
|
setlegendscheme(ls, **kwargs)
|
|
ls.setFieldName(field)
|
|
values = kwargs.pop('values', None)
|
|
if values is None:
|
|
return ls
|
|
else:
|
|
nls = LegendScheme(ls.getShapeType())
|
|
for v in values:
|
|
nls.addLegendBreak(ls.findLegendBreak(v))
|
|
return nls
|
|
|
|
n = len(args)
|
|
isunique = True
|
|
if n == 0:
|
|
ls = LegendManage.createSingleSymbolLegendScheme(shapetype)
|
|
setlegendscheme(ls, **kwargs)
|
|
elif n == 1 and isinstance(args[0], int):
|
|
ls = LegendManage.createUniqValueLegendScheme(args[0], shapetype)
|
|
setlegendscheme(ls, **kwargs)
|
|
else:
|
|
ls = LegendScheme(shapetype)
|
|
for arg in args:
|
|
if isinstance(arg, (list, tuple)):
|
|
for argi in arg:
|
|
lb, isu = getlegendbreak(geometry, **argi)
|
|
if isunique and not isu:
|
|
isunique = False
|
|
ls.addLegendBreak(lb)
|
|
else:
|
|
lb, isu = getlegendbreak(geometry, **arg)
|
|
if isunique and not isu:
|
|
isunique = False
|
|
ls.addLegendBreak(lb)
|
|
|
|
ls.setFieldName(field)
|
|
if ls.getBreakNum() > 1:
|
|
if isunique:
|
|
ls.setLegendType(LegendType.UNIQUE_VALUE)
|
|
else:
|
|
ls.setLegendType(LegendType.GRADUATED_COLOR)
|
|
|
|
return ls
|
|
|
|
|
|
def makelegend(source, **kwargs):
|
|
"""
|
|
Make a legend.
|
|
|
|
:param source: Legend file name or list of the legend breaks.
|
|
|
|
:returns: Created legend.
|
|
"""
|
|
if isinstance(source, basestring):
|
|
if os.path.exists(source):
|
|
ls = LegendScheme()
|
|
ls.importFromXMLFile(source, False)
|
|
return ls
|
|
else:
|
|
source = getcolormap(source)
|
|
else:
|
|
if isinstance(source, list):
|
|
if isinstance(source[0], ColorBreak):
|
|
ls = LegendScheme(source)
|
|
else:
|
|
colors = getcolors(source)
|
|
values = kwargs.pop('values', None)
|
|
if values is None:
|
|
cbs = []
|
|
for c in colors:
|
|
cb = ColorBreak()
|
|
cb.setColor(c)
|
|
cbs.append(cb)
|
|
ls = LegendScheme(cbs)
|
|
else:
|
|
ls = LegendManage.createLegendScheme(values, colors)
|
|
else:
|
|
values = kwargs.pop('values', None)
|
|
if values is None:
|
|
ls = None
|
|
else:
|
|
if isinstance(values, NDArray):
|
|
values = values.aslist()
|
|
cbs = source.findBreaks(values)
|
|
ls = LegendScheme(cbs)
|
|
return ls
|