mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
314 lines
9.2 KiB
Python
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)
|