314 lines
9.2 KiB
Python

from org.meteoinfo.geometry.graphic import GraphicCollection, Point2DGraphicCollection, \
Line2DGraphicCollection
from java.awt import Font
from .. import plotutil
from ... import miutil
from artist import Artist
import mipylib.numeric as np
__all__ = ['Point2DCollection','LineCollection']
class Collection(Artist):
def __init__(self):
"""
Class init.
:param graphics: (*GraphicCollection*) Graphics
"""
Artist.__init__(self)
def addlabels(self, texts=None, **kwargs):
"""
Add labels
:param texts: (*array of string*) Label texts. Default is ``None``, means using value of the graphics.
:param fontname: (*string*) Font name. Default is ``Arial``.
:param fontsize: (*string*) Font size. Default is ``14``.
:param bold: (*boolean*) Font bold or not. Default is ``False``.
:param color: (*color*) Label color. Default is ``None`` with black color.
:param xoffset: (*int*) X coordinate offset. Default is ``0``.
:param yoffset: (*int*) Y coordinate offset. Default is ``0``.
:param avoidcoll: (*boolean*) Avoid labels collision or not. Default is ``True``.
:param decimals: (*int*) Number of decimals of labels.
"""
labelset = self.getLabelSet()
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)
labelset.setLabelFont(font)
color = kwargs.pop('color', None)
if not color is None:
color = miutil.getcolor(color)
labelset.setLabelColor(color)
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 texts is None:
self.addLabels()
else:
texts = np.asarray(texts)
self.addLabels(texts._array)
class Point2DCollection(Collection, Point2DGraphicCollection):
def __init__(self, xdata, ydata, cdata=None, legend=None, **kwargs):
"""
Class init
:param xdata: (*Array*) X data array.
:param ydata: (*Array*) Y data array.
:param cdata: (*Array*) Color data array.
:param legend: (*Legend*) Point legend.
"""
Collection.__init__(self)
if legend is None:
legend = plotutil.getlegendbreak('point', **kwargs)[0]
self._x = np.asarray(xdata)
self._y = np.asarray(ydata)
self._cdata = np.asarray(cdata)
if cdata is None:
Point2DGraphicCollection.__init__(self, self._x._array, self._y._array, legend)
else:
Point2DGraphicCollection.__init__(self, self._x._array, self._y._array, self._cdata._array, legend)
@property
def visible(self):
"""
The artist is visible or not.
"""
return self.isVisible()
@visible.setter
def visible(self, val):
self.setVisible(val)
self.stale = True
@property
def xdata(self):
"""
Return the xdata.
:return: (*array*) xdata.
"""
return self._x
@xdata.setter
def xdata(self, xdata):
"""
Set the xdata.
:param xdata: (*array*) The xdata.
"""
self._x = xdata
self.setXData(xdata._array)
self.stale = True
@property
def ydata(self):
"""
Return the ydata.
:return: (*array*) ydata.
"""
return self._y
@ydata.setter
def ydata(self, ydata):
"""
Set the ydata.
:param ydata: (*array*) The ydata.
"""
self._y = ydata
self.setYData(ydata._array)
self.stale = True
@property
def data(self):
"""
Get x, y data.
:return: x, y data.
"""
return (self._x, self._y)
@data.setter
def data(self, *args):
"""
Set x, y data.
:param xdata: (*array*) X data.
:param ydata: (*array*) Y data.
"""
if len(args) == 1:
xdata = args[0][0]
ydata = args[0][1]
else:
xdata = args[0]
ydata = args[1]
self._x = xdata
self._y = ydata
self.setData(xdata._array, ydata._array)
self.stale = True
class LineCollection(Collection, Line2DGraphicCollection):
def __init__(self, segments, legend=None, **kwargs):
"""
Class init
Parameters
----------
segments : list of Array
A sequence (*line0*, *line1*, *line2*) of lines, where each line is a list
of points::
lineN = [(x0, y0), (x1, y1), ... (xm, ym)]
or the equivalent Mx2 numpy array with two columns. Each line
can have a different number of segments.
legend : Legend
Point legend.
xydata : List array
X and Y 2D coordinates data array for lines.
array : Array
Array data for line colors.
cdata : Array
Color data array to plot multiple color lines.
"""
Collection.__init__(self)
if segments is None:
xydata = kwargs.pop('xydata', None)
if xydata is None:
raise ValueError('Segments data is None!')
else:
if len(xydata) == 1:
ydata = xydata[0]
xdata = None
else:
xdata = xydata[0]
ydata = xydata[1]
nseg, nline = ydata.shape
if xdata is None:
xdata = np.arange(nseg)
if xdata.ndim == 1:
segments = [np.column_stack([xdata, ydata[:,i]]) for i in range(nline)]
else:
segments = [np.column_stack([xdata[:,i], ydata[:,i]]) for i in range(nline)]
if isinstance(segments, np.NDArray):
self._segments = []
ns = segments.shape[0]
for i in range(ns):
self._segments.append(segments[i])
else:
self._segments = segments
data = []
for s in self._segments:
data.append(s._array)
self._array = kwargs.pop('array', None)
self._cdata = kwargs.pop('cdata', None)
if self._array is None and self._cdata is None:
if legend is None:
legend = plotutil.getlegendbreak('line', **kwargs)[0]
kwargs['ncolors'] = len(self._segments)
legend = plotutil.getlegendbreaks(legend, **kwargs)
Line2DGraphicCollection.__init__(self, data, legend)
else:
if self._array is not None:
if legend is None:
legend = plotutil.getlegendscheme([len(self._segments)], self._array.min(), self._array.max(), **kwargs)
legend = plotutil.setlegendscheme_line(legend, **kwargs)
Line2DGraphicCollection.__init__(self, data, self._array._array, legend)
else:
if legend is None:
legend = plotutil.getlegendscheme([], self._cdata.min(), self._cdata.max(), **kwargs)
legend = plotutil.setlegendscheme_line(legend, **kwargs)
Line2DGraphicCollection.__init__(self, data, self._cdata._array, legend)
antialias = kwargs.pop('antialias', None)
if antialias is not None:
self.setAntiAlias(antialias)
@property
def visible(self):
"""
The artist is visible or not.
"""
return self.isVisible()
@visible.setter
def visible(self, val):
self.setVisible(val)
self.stale = True
@property
def segments(self):
return self._segments
@segments.setter
def segments(self, val):
self._segments = val
data = []
for s in self._segments:
data.append(s._array)
self.setData(data)
self.stale = True
def set_segments(self, val, cdata=None):
if cdata is None:
self.segments = val
else:
self._segments = val
data = []
for s in self._segments:
data.append(s._array)
self.setData(data, cdata._array)
self.stale = True
def set_xydata(self, xydata, cdata=None):
if len(xydata) == 1:
ydata = xydata[0]
xdata = None
else:
xdata = xydata[0]
ydata = xydata[1]
nseg, nline = ydata.shape
if xdata is None:
xdata = np.arange(nseg)
if xdata.ndim == 1:
segments = [np.column_stack([xdata, ydata[:,i]]) for i in range(nline)]
else:
segments = [np.column_stack([xdata[:,i], ydata[:,i]]) for i in range(nline)]
self.set_segments(segments, cdata=cdata)