# coding=utf-8 #----------------------------------------------------- # Author: Yaqiang Wang # Date: 2018-4-10 # Purpose: MeteoInfoLab axes3d module # Note: Jython #----------------------------------------------------- from org.meteoinfo.chart.plot import Plot3D from org.meteoinfo.chart.graphic import GraphicFactory from org.meteoinfo.chart import ChartText3D from org.meteoinfo.chart.axis import Axis, LonLatAxis, TimeAxis, LogAxis from org.meteoinfo.geo.legend import LegendManage from org.meteoinfo.geometry.legend import BreakTypes, PolylineBreak from org.meteoinfo.geometry.shape import ShapeTypes from org.meteoinfo.geometry.graphic import Graphic from org.meteoinfo.geo.layer import LayerTypes from org.meteoinfo.common import Extent3D from ._axes import Axes from mipylib.numeric.core import NDArray, DimArray import mipylib.numeric as np import plotutil import mipylib.miutil as miutil from mipylib import migl from mipylib.geolib import migeo import os import datetime import numbers import warnings from java.awt import Font, Color, BasicStroke __all__ = ['Axes3D'] ######################################################### class Axes3D(Axes): """ Axes with 3 dimensional. """ def __init__(self, *args, **kwargs): axes = kwargs.pop('axes', None) self._set_plot(axes) figure = kwargs.pop('figure', None) self.figure = figure if len(args) > 0: position = args[0] else: position = kwargs.pop('position', None) outerposition = kwargs.pop('outerposition', None) if position is None: position = [0.13, 0.11, 0.71, 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) 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.setAxisTickFont(font) self.projector = self._axes.getProjector() #distance = kwargs.pop('distance', 10000) #self.projector.setDistance(distance) rotation_angle = kwargs.pop('rotation', 225) self.projector.setRotationAngle(rotation_angle) elevation_angle = kwargs.pop('elevation', 30) self.projector.setElevationAngle(elevation_angle) xyaxis = kwargs.pop('xyaxis', True) self._axes.setDisplayXY(xyaxis) zaxis = kwargs.pop('zaxis', True) self._axes.setDisplayZ(zaxis) grid = kwargs.pop('grid', True) grid_line = self._axes.getGridLine() grid_line.setDrawXLine(grid) grid_line.setDrawYLine(grid) grid_line.setDrawZLine(grid) boxed = kwargs.pop('boxed', True) self._axes.setBoxed(boxed) bbox = kwargs.pop('bbox', False) self._axes.setDrawBoundingBox(bbox) def _set_plot(self, plot): """ Set plot. :param plot: (*Plot3D*) Plot. """ if plot is None: self._axes = Plot3D() else: self._axes = plot @property def axestype(self): return '3d' @property def ndim(self): """ Dimension number property """ return 3 def get_distance(self): """ Get distance to object. :returns: Distance to object. """ return self.projector.getDistance() def set_distance(self, dis): """ Set distance to object. :param dis: (*float*) Distance to object. """ self.projector.setDistance(dis) def get_rotation(self): """ Get rotation angle. :returns: Rotation angle. """ return self.projector.getRotationAngle() def set_rotation(self, rotation): """ Set rotation angle. :param rotation: (*float*) Rotation angle. """ self.projector.setRotationAngle(rotation) def get_elevation(self): """ Get elevation angle. :returns: Elevation angle. """ return self.projector.getElevationAngle() def set_elevation(self, elevation): """ Set elevation angle. :param elevation: (*float*) Elevation angle. """ self.projector.setElevationAngle(elevation) def set_draw_xy(self, dxy): """ Set draw xy axis or not. :param dxy: (*boolean*) Draw xy axis or not. """ self._axes.setDisplayXY(dxy) def set_draw_z(self, dz): """ Set draw z axis or not. :param dz: (*boolean*) Draw z axis or not. """ self._axes.setDisplayZ(dz) def set_draw_base(self, is_draw): """ Set draw base area or not. :param is_draw: (*bool*) Draw base area or not. """ self._axes.setDrawBase(is_draw) def set_draw_box(self, db): """ Set draw 3D box or not. :param db: (*boolean*) Draw 3D box or not. """ self._axes.setBoxed(db) def set_draw_bbox(self, bbox): """ Set draw bounding box or not. :param bbox: (*boolean*) Draw bounding box or not. """ self._axes.setDrawBoundingBox(bbox) def set_draw_axis(self, axis): """ Set whether draw axis. :param axis: (*bool*) Whether draw axis. """ self.set_draw_base(axis) self.set_draw_bbox(axis) self.set_draw_box(axis) self.set_draw_xy(axis) self.set_draw_z(axis) def set_box_color(self, color): """ Set box fill color. :param color: (*color*) Box fill color. """ color = plotutil.getcolor(color) self._axes.setBoxColor(color) def get_xlim(self): """ Get the *x* limits of the current axes. :returns: (*tuple*) x limits. """ return self._axes.getXMin(), self._axes.getXMax() 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) self._axes.setXMinMax(xmin, xmax) def get_ylim(self): """ Get the *y* limits of the current axes. :returns: (*tuple*) y limits. """ return self._axes.getYMin(), self._axes.getYMax() def set_ylim(self, ymin, ymax): """ Set the *y* 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) self._axes.setYMinMax(ymin, ymax) def get_zlim(self): """ Get the *z* limits of the current axes. :returns: (*tuple*) z limits. """ return self._axes.getZMin(), self._axes.getZMax() def set_zlim(self, zmin, zmax): """ Set the *z* limits of the current axes. :param zmin: (*float*) Minimum limit of the z axis. :param zmax: (*float*) Maximum limit of the z axis. """ if isinstance(zmin, datetime.datetime): zmin = miutil.date2num(zmin) if isinstance(zmax, datetime.datetime): zmax = miutil.date2num(zmax) self._axes.setZMinMax(zmin, zmax) def axis(self, limits): """ Sets the min and max of the x,y, axes, with ``[xmin, xmax, ymin, ymax, zmin, zmax]`` . :param limits: (*list*) Min and max of the x,y,z axes. """ if len(limits) == 6: xmin = limits[0] xmax = limits[1] ymin = limits[2] ymax = limits[3] zmin = limits[4] zmax = limits[5] extent = Extent3D(xmin, xmax, ymin, ymax, zmin, zmax) self._axes.setDrawExtent(extent) self._axes.setAxesExtent(extent.clone()) return True else: print('The limits parameter must be a list with 6 elements: xmin, xmax, ymin, ymax, zmin, zmax!') return None def set_zlabel(self, label, **kwargs): """ Set the z 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.getZAxis() axis.setLabel(ctext) axis.setDrawLabel(True) def get_zticks(self): """ Get z axis tick locations. """ axis = self._axes.getZAxis() axis.updateTickLabels() return axis.getTickLocations() def set_zticks(self, locs): """ Set z axis tick locations. """ axis = self._axes.getZAxis() if isinstance(locs, (NDArray, DimArray)): locs = labels.aslist() axis.setTickLocations(locs) def get_zticklabels(self): """ Get z axis tick labels. """ axis = self._axes.getZAxis() axis.updateTickLabels() return axis.getTickLabelText() def set_zticklabels(self, labels, **kwargs): """ Set z axis tick labels. """ axis = self._axes.getZAxis() 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) 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) 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 if axistype == 'lon': axis = LonLatAxis(ax.getXAxis()) axis.setLongitude(False) ax.setXAxis(axis) elif axistype == 'lat': axis = LonLatAxis(ax.getXAxis()) axis.setLongitude(False) ax.setXAxis(axis) elif axistype == 'time': axis = TimeAxis(ax.getXAxis()) ax.setXAxis(axis) if not timetickformat is None: ax.getXAxis().setTimeFormat(timetickformat) elif axistype == 'log': axis = LogAxis(ax.getXAxis()) axis.setMinorTickNum(10) ax.setXAxis(axis) else: axis = Axis(ax.getXAxis()) ax.setXAxis(axis) 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': axis = LonLatAxis(ax.getYAxis()) axis.setLongitude(True) ax.setYAxis(axis) elif axistype == 'lat': axis = LonLatAxis(ax.getYAxis()) axis.setLongitude(False) ax.setYAxis(axis) elif axistype == 'time': axis = TimeAxis(ax.getYAxis()) ax.setYAxis(axis) if not timetickformat is None: ax.getYAxis().setTimeFormat(timetickformat) elif axistype == 'log': axis = LogAxis(ax.getYAxis()) axis.setMinorTickNum(10) ax.setYAxis(axis) else: axis = Axis(ax.getYAxis()) ax.setYAxis(axis) def set_zaxis_type(self, axistype, timetickformat=None): """ Set z axis type. :param axistype: (*string*) Axis type ['lon' | 'lat' | 'time' | 'log']. :param timetickformat: (*string*) Time tick label format. """ ax = self._axes if axistype == 'lon': axis = LonLatAxis(ax.getZAxis()) axis.setLongitude(True) ax.setZAxis(axis) elif axistype == 'lat': axis = LonLatAxis(ax.getZAxis()) axis.setLongitude(False) ax.setZAxis(axis) elif axistype == 'time': axis = TimeAxis(ax.getZAxis()) ax.setZAxis(axis) if not timetickformat is None: ax.getZAxis().setTimeFormat(timetickformat) elif axistype == 'log': axis = LogAxis(ax.getZAxis()) axis.setMinorTickNum(10) ax.setZAxis(axis) else: axis = Axis(ax.getZAxis()) ax.setZAxis(axis) def zaxis(self, **kwargs): """ Set z axis of the axes. :param color: (*Color*) Color of the z axis. Default is 'black'. :param shift: (*int) z axis shif along horizontal direction. Units is pixel. Default is 0. """ visible = kwargs.pop('visible', None) shift = kwargs.pop('shift', None) color = kwargs.pop('color', None) if not color is None: color = plotutil.getcolor(color) linewidth = kwargs.pop('linewidth', None) linestyle = kwargs.pop('linestyle', None) tickcolor = kwargs.pop('tickcolor', None) if not tickcolor is None: tickcolor = plotutil.getcolor(tickcolor) tickline = kwargs.pop('tickline', None) tickline = kwargs.pop('tickvisible', tickline) tickwidth = kwargs.pop('tickwidth', None) ticklabel = kwargs.pop('ticklabel', None) minortick = kwargs.pop('minortick', False) minorticknum = kwargs.pop('minorticknum', 5) tickin = kwargs.pop('tickin', True) axistype = kwargs.pop('axistype', None) ticklabelcolor= kwargs.pop('ticklabelcolor', None) if not ticklabelcolor is None: ticklabelcolor = plotutil.getcolor(ticklabelcolor) 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) axislist = [] axislist.append(self._axes.getZAxis()) for axis in axislist: if not visible is None: axis.setVisible(visible) if not shift is None: axis.setShift(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 ticklabel is None: axis.setDrawTickLabel(ticklabel) axis.setMinorTickVisible(minortick) axis.setMinorTickNum(minorticknum) axis.setInsideTick(tickin) if not ticklabelcolor is None: axis.setTickLabelColor(ticklabelcolor) axis.setTickLabelFont(font) def grid(self, b, **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 kwargs: *kwargs* are used to set the grid line properties. """ gridline = self._axes.getGridLine() if b is None: b = not gridline.isDrawZLine() axis = kwargs.pop('axis', 'all') if axis == 'all': gridline.setDrawXLine(b) gridline.setDrawYLine(b) gridline.setDrawZLine(b) elif axis == 'x': gridline.setDrawXLine(b) elif axis == 'y': gridline.setDrawYLine(b) elif axis == 'z': gridline.setDrawZLine(b) color = kwargs.pop('color', None) if not color is None: c = plotutil.getcolor(color) gridline.setColor(c) linewidth = kwargs.pop('linewidth', None) if not linewidth is None: gridline.setSize(linewidth) linestyle = kwargs.pop('linestyle', None) if not linestyle is None: linestyle = plotutil.getlinestyle(linestyle) gridline.setStyle(linestyle) def plot(self, x, y, z, *args, **kwargs): """ Plot 3D 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 z: (*array_like*) Input z 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 ========= ===== """ xdata = plotutil.getplotdata(x) ydata = plotutil.getplotdata(y) zdata = plotutil.getplotdata(z) style = None if len(args) > 0: style = args[0] #Set plot data styles label = kwargs.pop('label', 'S_1') mvalues = kwargs.pop('mvalues', None) cdata = kwargs.pop('cdata', mvalues) if cdata is None: if style is None: line = plotutil.getlegendbreak('line', **kwargs)[0] line.setCaption(label) else: line = plotutil.getplotstyle(style, label, **kwargs) colors = kwargs.pop('colors', None) if not colors is None: colors = plotutil.getcolors(colors) cbs = [] for color in colors: cb = line.clone() cb.setColor(color) cbs.append(cb) else: ls = kwargs.pop('symbolspec', None) if ls is None: if isinstance(cdata, (list, tuple)): cdata = np.array(cdata) 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([], 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) #Add graphics if cdata is None: if colors is None: graphics = GraphicFactory.createLineString3D(xdata, ydata, zdata, line) else: graphics = GraphicFactory.createLineString3D(xdata, ydata, zdata, cbs) else: cdata = plotutil.getplotdata(cdata) graphics = GraphicFactory.createLineString3D(xdata, ydata, zdata, cdata, ls) #Pipe pipe = kwargs.pop('pipe', False) if pipe: radius = kwargs.pop('radius', 0.02) steps = kwargs.pop('steps', 48) graphics = GraphicFactory.lineString3DToPipe(graphics, radius, steps) lighting = kwargs.pop('lighting', None) if not lighting is None: graphics.setUsingLight(lighting) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def scatter(self, x, y, z, s=8, c='b', marker='o', **kwargs): """ Make a 3D scatter plot of x, y and z, where x, y and z are sequence like objects of the same lengths. :param x: (*array_like*) Input x data. :param y: (*array_like*) Input y data. :param z: (*array_like*) Input z data. :param s: (*int*) Size of points. :param c: (*Color*) Color of the points. Or z vlaues. :param alpha: (*int*) The alpha blending value, between 0 (transparent) and 1 (opaque). :param marker: (*string*) Marker of the points. :param label: (*string*) Label of the points series. :param levels: (*array_like*) Optional. A list of floating point numbers indicating the level points to draw, in increasing order. :returns: Point 3D graphics. """ #Add data series label = kwargs.pop('label', 'S_0') xdata = plotutil.getplotdata(x) ydata = plotutil.getplotdata(y) zdata = plotutil.getplotdata(z) #Set plot data styles pb, isunique = plotutil.getlegendbreak('point', **kwargs) pb.setCaption(label) pstyle = plotutil.getpointstyle(marker) pb.setStyle(pstyle) isvalue = False if isinstance(c, (NDArray, DimArray)): isvalue = True elif isinstance(c, (list, tuple)): if isinstance(c[0], numbers.Number): 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.createPoints3D(xdata, ydata, zdata, c.asarray(), ls) else: alpha = kwargs.pop('alpha', None) colors = plotutil.getcolors(c, alpha) pbs = [] if isinstance(s, int): pb.setSize(s) if len(colors) == 1: pb.setColor(colors[0]) pbs.append(pb) else: n = len(colors) for i in range(0, n): npb = pb.clone() npb.setColor(colors[i]) pbs.append(npb) else: n = len(s) if len(colors) == 1: pb.setColor(colors[0]) for i in range(0, n): npb = pb.clone() npb.setSize(s[i]) pbs.append(npb) else: for i in range(0, n): npb = pb.clone() npb.setSize(s[i]) npb.setColor(colors[i]) pbs.append(npb) #Create graphics graphics = GraphicFactory.createPoints3D(xdata, ydata, zdata, pbs) sphere = kwargs.pop('sphere', None) if not sphere is None: graphics.setSphere(sphere) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def stem(self, x, y, z, s=8, c='b', marker='o', alpha=None, linewidth=None, verts=None, **kwargs): """ Make a 3D scatter plot of x, y and z, where x, y and z are sequence like objects of the same lengths. :param x: (*array_like*) Input x data. :param y: (*array_like*) Input y data. :param z: (*array_like*) Input z data. :param s: (*int*) Size of points. :param c: (*Color*) Color of the points. Or z vlaues. :param alpha: (*int*) The alpha blending value, between 0 (transparent) and 1 (opaque). :param marker: (*string*) Marker of the points. :param label: (*string*) Label of the points series. :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level points to draw, in increasing order. :returns: Stem graphics. """ #Add data series label = kwargs.pop('label', 'S_0') xdata = plotutil.getplotdata(x) ydata = plotutil.getplotdata(y) zdata = plotutil.getplotdata(z) #Set plot data styles pb, isunique = plotutil.getlegendbreak('point', **kwargs) pb.setCaption(label) pstyle = plotutil.getpointstyle(marker) pb.setStyle(pstyle) bottom = kwargs.pop('bottom', 0) samestemcolor = kwargs.pop('samestemcolor', False) isvalue = False if len(c) > 1: if isinstance(c, (NDArray, DimArray)): isvalue = True elif 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]) linefmt = kwargs.pop('linefmt', None) if linefmt is None: linefmt = PolylineBreak() linefmt.setColor(Color.black) else: linefmt = plotutil.getlegendbreak('line', **linefmt)[0] #Create graphics graphics = GraphicFactory.createStems3D(xdata, ydata, zdata, c.asarray(), \ ls, linefmt, bottom, samestemcolor) else: colors = plotutil.getcolors(c, alpha) pbs = [] if isinstance(s, int): pb.setSize(s) if len(colors) == 1: pb.setColor(colors[0]) pb.setOutlineColor(colors[0]) pbs.append(pb) else: n = len(colors) for i in range(0, n): npb = pb.clone() npb.setColor(colors[i]) npb.setOutlineColor(colors[i]) pbs.append(npb) else: n = len(s) if len(colors) == 1: pb.setColor(colors[0]) pb.setOutlineColor(colors[0]) for i in range(0, n): npb = pb.clone() npb.setSize(s[i]) pbs.append(npb) else: for i in range(0, n): npb = pb.clone() npb.setSize(s[i]) npb.setColor(colors[i]) npb.setOutlineColor(colors[i]) pbs.append(npb) linefmt = kwargs.pop('linefmt', None) if linefmt is None: linefmt = PolylineBreak() linefmt.setColor(colors[0]) else: linefmt = plotutil.getlegendbreak('line', **linefmt)[0] #Create graphics graphics = GraphicFactory.createStems3D(xdata, ydata, zdata, pbs, linefmt, \ bottom, samestemcolor) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics[0]) self.add_graphic(graphics[1]) return graphics[0], graphics[1] def mesh(self, *args, **kwargs): """ creates a three-dimensional wireframe 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 cmap: (*string*) Color map string. :param xyaxis: (*boolean*) Draw x and y axis or not. :param zaxis: (*boolean*) Draw z axis or not. :param grid: (*boolean*) Draw grid or not. :param boxed: (*boolean*) Draw boxed or not. :param mesh: (*boolean*) Draw mesh line or not. :returns: Mesh graphics """ if len(args) == 1: x = args[0].dimvalue(1) y = args[0].dimvalue(0) x, y = np.meshgrid(x, y) z = args[0] args = args[1:] else: x = args[0] y = args[1] z = args[2] args = args[3:] zcolors = kwargs.pop('zcolors', False) if not zcolors: line = plotutil.getlegendbreak('line', **kwargs)[0] graphics = GraphicFactory.createWireframe(x.asarray(), y.asarray(), z.asarray(), line) else: cmap = plotutil.getcolormap(**kwargs) if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createLegendScheme(z.min(), z.max(), cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createLegendScheme(z.min(), z.max(), level_arg, cmap) else: ls = LegendManage.createLegendScheme(z.min(), z.max(), cmap) ls = ls.convertTo(ShapeTypes.POLYLINE) plotutil.setlegendscheme(ls, **kwargs) graphics = GraphicFactory.createWireframe(x.asarray(), y.asarray(), z.asarray(), ls) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def plot_wireframe(self, *args, **kwargs): """ creates a three-dimensional wireframe 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 cmap: (*string*) Color map string. :param xyaxis: (*boolean*) Draw x and y axis or not. :param zaxis: (*boolean*) Draw z axis or not. :param grid: (*boolean*) Draw grid or not. :param boxed: (*boolean*) Draw boxed or not. :param mesh: (*boolean*) Draw mesh line or not. :returns: Legend """ warnings.warn("plot_wireframe is deprecated", DeprecationWarning) if len(args) == 1: x = args[0].dimvalue(1) y = args[0].dimvalue(0) x, y = np.meshgrid(x, y) z = args[0] args = args[1:] else: x = args[0] y = args[1] z = args[2] args = args[3:] zcolors = kwargs.pop('zcolors', False) if not zcolors: line = plotutil.getlegendbreak('line', **kwargs)[0] graphics = GraphicFactory.createWireframe(x.asarray(), y.asarray(), z.asarray(), line) else: cmap = plotutil.getcolormap(**kwargs) if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createLegendScheme(z.min(), z.max(), cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createLegendScheme(z.min(), z.max(), level_arg, cmap) else: ls = LegendManage.createLegendScheme(z.min(), z.max(), cmap) ls = ls.convertTo(ShapeTypes.POLYLINE) plotutil.setlegendscheme(ls, **kwargs) graphics = GraphicFactory.createWireframe(x.asarray(), y.asarray(), z.asarray(), ls) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def surf(self, *args, **kwargs): """ creates a three-dimensional surface 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 cmap: (*string*) Color map string. :param xyaxis: (*boolean*) Draw x and y axis or not. :param zaxis: (*boolean*) Draw z axis or not. :param grid: (*boolean*) Draw grid or not. :param boxed: (*boolean*) Draw boxed or not. :param mesh: (*boolean*) Draw mesh line or not. :returns: Legend """ if len(args) <= 2: x = args[0].dimvalue(1) y = args[0].dimvalue(0) x, y = np.meshgrid(x, y) z = args[0] args = args[1:] else: x = args[0] y = args[1] z = args[2] args = args[3:] cmap = plotutil.getcolormap(**kwargs) if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createLegendScheme(z.min(), z.max(), cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createLegendScheme(z.min(), z.max(), level_arg, cmap) else: ls = LegendManage.createLegendScheme(z.min(), z.max(), cmap) ls = ls.convertTo(ShapeTypes.POLYGON) edge = kwargs.pop('edge', True) kwargs['edge'] = edge plotutil.setlegendscheme(ls, **kwargs) graphics = GraphicFactory.createMeshPolygons(x.asarray(), y.asarray(), z.asarray(), ls) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def plot_surface(self, *args, **kwargs): """ creates a three-dimensional surface 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 cmap: (*string*) Color map string. :param xyaxis: (*boolean*) Draw x and y axis or not. :param zaxis: (*boolean*) Draw z axis or not. :param grid: (*boolean*) Draw grid or not. :param boxed: (*boolean*) Draw boxed or not. :param mesh: (*boolean*) Draw mesh line or not. :returns: Legend """ warnings.warn("plot_surface is deprecated", DeprecationWarning) if len(args) <= 2: x = args[0].dimvalue(1) y = args[0].dimvalue(0) x, y = np.meshgrid(x, y) z = args[0] args = args[1:] else: x = args[0] y = args[1] z = args[2] args = args[3:] cmap = plotutil.getcolormap(**kwargs) if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createLegendScheme(z.min(), z.max(), cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createLegendScheme(z.min(), z.max(), level_arg, cmap) else: ls = LegendManage.createLegendScheme(z.min(), z.max(), cmap) ls = ls.convertTo(ShapeTypes.POLYGON) edge = kwargs.pop('edge', True) kwargs['edge'] = edge plotutil.setlegendscheme(ls, **kwargs) graphics = GraphicFactory.createMeshPolygons(x.asarray(), y.asarray(), z.asarray(), ls) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def contour(self, *args, **kwargs): """ Plot contours. :param x: (*array_like*) Optional. X coordinate array. :param y: (*array_like*) Optional. Y coordinate array. :param z: (*array_like*) 2-D z value array. :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves to draw, in increasing order. :param cmap: (*string*) Color map string. :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. :param smooth: (*boolean*) Smooth countour lines or not. :returns: (*VectoryLayer*) Contour VectoryLayer created from array data. """ n = len(args) cmap = plotutil.getcolormap(**kwargs) fill_value = kwargs.pop('fill_value', -9999.0) offset = kwargs.pop('offset', 0) xaxistype = None if n <= 2: gdata = np.asgriddata(args[0]) if isinstance(args[0], DimArray): if args[0].islondim(1): xaxistype = 'lon' elif args[0].islatdim(1): xaxistype = 'lat' elif args[0].istimedim(1): xaxistype = 'time' args = args[1:] elif n <=4: x = args[0] y = args[1] a = args[2] gdata = np.asgriddata(a, x, y, fill_value) args = args[3:] if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createLegendScheme(gdata.min(), gdata.max(), cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createLegendScheme(gdata.min(), gdata.max(), level_arg, cmap) else: ls = LegendManage.createLegendScheme(gdata.min(), gdata.max(), cmap) ls = ls.convertTo(ShapeTypes.POLYLINE) plotutil.setlegendscheme(ls, **kwargs) smooth = kwargs.pop('smooth', True) zdir = kwargs.pop('zdir', 'z') if zdir == 'xy': sepoint = kwargs.pop('sepoint', [0,0,1,1]) igraphic = GraphicFactory.createContourLines(gdata.data, offset, zdir, ls, smooth, \ sepoint) else: igraphic = GraphicFactory.createContourLines(gdata.data, offset, zdir, ls, smooth) lighting = kwargs.pop('lighting', None) if not lighting is None: igraphic.setUsingLight(lighting) visible = kwargs.pop('visible', True) if visible: self.add_graphic(igraphic) return igraphic def contourf(self, *args, **kwargs): """ Plot filled contours. :param x: (*array_like*) Optional. X coordinate array. :param y: (*array_like*) Optional. Y coordinate array. :param z: (*array_like*) 2-D z value array. :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves to draw, in increasing order. :param cmap: (*string*) Color map string. :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. :param smooth: (*boolean*) Smooth countour lines or not. :returns: (*VectoryLayer*) Contour VectoryLayer created from array data. """ n = len(args) cmap = plotutil.getcolormap(**kwargs) fill_value = kwargs.pop('fill_value', -9999.0) offset = kwargs.pop('offset', 0) xaxistype = None if n <= 2: gdata = np.asgriddata(args[0]) if isinstance(args[0], DimArray): if args[0].islondim(1): xaxistype = 'lon' elif args[0].islatdim(1): xaxistype = 'lat' elif args[0].istimedim(1): xaxistype = 'time' args = args[1:] elif n <=4: x = args[0] y = args[1] a = args[2] gdata = np.asgriddata(a, x, y, fill_value) args = args[3:] if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createLegendScheme(gdata.min(), gdata.max(), cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createLegendScheme(gdata.min(), gdata.max(), level_arg, cmap) else: ls = LegendManage.createLegendScheme(gdata.min(), gdata.max(), cmap) ls = ls.convertTo(ShapeTypes.POLYGON) if not kwargs.has_key('edgecolor'): kwargs['edgecolor'] = None plotutil.setlegendscheme(ls, **kwargs) smooth = kwargs.pop('smooth', True) zdir = kwargs.pop('zdir', 'z') if zdir == 'xy': sepoint = kwargs.pop('sepoint', [0,0,1,1]) igraphic = GraphicFactory.createContourPolygons(gdata.data, offset, zdir, ls, smooth, \ sepoint) else: igraphic = GraphicFactory.createContourPolygons(gdata.data, offset, zdir, ls, smooth) visible = kwargs.pop('visible', True) if visible: self.add_graphic(igraphic) return igraphic def imshow(self, *args, **kwargs): """ Display an image on the 3D axes. :param x: (*array_like*) Optional. X coordinate array. :param y: (*array_like*) Optional. Y coordinate array. :param z: (*array_like*) 2-D or 3-D (RGB) 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: (*RasterLayer*) RasterLayer created from array data. """ n = len(args) cmap = plotutil.getcolormap(**kwargs) fill_value = kwargs.pop('fill_value', -9999.0) xaxistype = None isrgb = False if n <= 2: if isinstance(args[0], (list, tuple)): isrgb = True rgbdata = args[0] if isinstance(rgbdata[0], NDArray): x = np.arange(0, rgbdata[0].shape[1]) y = np.arange(0, rgbdata[0].shape[0]) else: x = rgbdata[0].dimvalue(1) y = rgbdata[0].dimvalue(0) elif args[0].ndim > 2: isrgb = True rgbdata = args[0] if isinstance(rgbdata, NDArray): x = np.arange(0, rgbdata.shape[1]) y = np.arange(0, rgbdata.shape[0]) else: x = rgbdata.dimvalue(1) y = rgbdata.dimvalue(0) else: gdata = np.asgridarray(args[0]) if isinstance(args[0], DimArray): if args[0].islondim(1): xaxistype = 'lon' elif args[0].islatdim(1): xaxistype = 'lat' elif args[0].istimedim(1): xaxistype = 'time' args = args[1:] elif n <=4: x = args[0] y = args[1] a = args[2] if isinstance(a, (list, tuple)): isrgb = True rgbdata = a elif a.ndim > 2: isrgb = True rgbdata = a else: gdata = np.asgridarray(a, x, y, fill_value) args = args[3:] offset = kwargs.pop('offset', 0) zdir = kwargs.pop('zdir', 'z') interpolation = kwargs.pop('interpolation', None) if isrgb: if isinstance(rgbdata, (list, tuple)): rgbd = [] for d in rgbdata: rgbd.append(d.asarray()) rgbdata = rgbd else: rgbdata = rgbdata.asarray() x = plotutil.getplotdata(x) y = plotutil.getplotdata(y) graphics = GraphicFactory.createImage(x, y, rgbdata, offset, zdir, interpolation) ls = None else: if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createImageLegend(gdata, cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createImageLegend(gdata, level_arg, cmap) else: ls = plotutil.getlegendscheme(args, gdata.min(), gdata.max(), **kwargs) ls = ls.convertTo(ShapeTypes.IMAGE) plotutil.setlegendscheme(ls, **kwargs) if zdir == 'xy': sepoint = kwargs.pop('sepoint', [0,0,1,1]) else: sepoint = None graphics = GraphicFactory.createImage(gdata, ls, offset, zdir, sepoint, interpolation) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def quiver(self, *args, **kwargs): """ Plot a 3-D field of arrows. :param x: (*array_like*) X coordinate array. :param y: (*array_like*) Y coordinate array. :param z: (*array_like*) Z coordinate array. :param u: (*array_like*) U component of the arrow vectors (wind field). :param v: (*array_like*) V component of the arrow vectors (wind field). :param w: (*array_like*) W component of the arrow vectors (wind field). :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 scale: (*float*) The length scale of each quiver, default to 1.0, the unit is the same with the axes. :param headwidth: (*float*) Arrow head width, default is 1. :param headlength: (*float*) Arrow head length, default is 2.5. :returns: (*Graphic list*) Created quiver graphics. """ ls = kwargs.pop('symbolspec', None) cmap = plotutil.getcolormap(**kwargs) fill_value = kwargs.pop('fill_value', -9999.0) n = len(args) iscolor = False cdata = None xaxistype = None x = args[0] y = args[1] z = args[2] u = args[3] v = args[4] w = args[5] args = args[6:] if len(args) > 0: cdata = args[0] iscolor = True args = args[1:] x = plotutil.getplotdata(x) y = plotutil.getplotdata(y) z = plotutil.getplotdata(z) u = plotutil.getplotdata(u) v = plotutil.getplotdata(v) w = plotutil.getplotdata(w) 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_point(ls, **kwargs) if not cdata is None: cdata = plotutil.getplotdata(cdata) scale = kwargs.pop('scale', 1) headwidth = kwargs.pop('headwidth', 1) headlength = kwargs.pop('headlength', 2.5) igraphic = GraphicFactory.createArrows3D(x, y, z, u, v, w, scale, headwidth, headlength, cdata, ls) lighting = kwargs.pop('lighting', None) if not lighting is None: igraphic.setUsingLight(lighting) visible = kwargs.pop('visible', True) if visible: self.add_graphic(igraphic) return igraphic def geoshow(self, layer, **kwargs): """ Plot a layer map in 3D axes. :param layer: (*str or MILayer*) The layer to be plotted. :param offset: (*float*) Location on z axis. :param xshift: (*float*) X coordinate shift. :param facecolor: (*color*) Face color. :param edgecolor: (*color*) Edge color. :param linewidth: (*float*) Line width. :returns: Graphics. """ ls = kwargs.pop('symbolspec', None) offset = kwargs.pop('offset', 0) xshift = kwargs.pop('xshift', 0) if isinstance(layer, basestring): fn = layer encoding = kwargs.pop('encoding', None) layer = migeo.georead(fn, encoding) layer = layer._layer if layer.getLayerType() == LayerTypes.VECTOR_LAYER: if ls is None: ls = layer.getLegendScheme() if len(kwargs) > 0 and layer.getLegendScheme().getBreakNum() == 1: lb = layer.getLegendScheme().getLegendBreaks().get(0) btype = lb.getBreakType() geometry = 'point' if btype == BreakTypes.POLYLINE_BREAK: geometry = 'line' elif btype == BreakTypes.POLYGON_BREAK: geometry = 'polygon' if not kwargs.has_key('facecolor'): kwargs['facecolor'] = None if not kwargs.has_key('edgecolor'): kwargs['edgecolor'] = 'k' lb, isunique = plotutil.getlegendbreak(geometry, **kwargs) ls.getLegendBreaks().set(0, lb) plotutil.setlegendscheme(ls, **kwargs) layer.setLegendScheme(ls) graphics = GraphicFactory.createGraphicsFromLayer(layer, offset, xshift) else: interpolation = kwargs.pop('interpolation', None) graphics = GraphicFactory.createImage(layer, offset, xshift, interpolation) lighting = kwargs.pop('lighting', None) if not lighting is None: graphics.setUsingLight(lighting) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def plot_layer(self, layer, **kwargs): """ Plot a layer in 3D axes. :param layer: (*MILayer*) The layer to be plotted. :returns: Graphics. """ warnings.warn("plot_layer is deprecated", DeprecationWarning) return self.geoshow(layer, **kwargs) 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``. """ #Get dataset global gca #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 offset = kwargs.pop('offset', 0) zdir = kwargs.pop('zdir', 'z') if zdir == 'xy': y = kwargs.pop('y', x) ydata = plotutil.getplotdata(y) graphics = GraphicFactory.createFillBetweenPolygons(xdata, ydata, y1, y2, where, pb, \ offset, zdir) else: graphics = GraphicFactory.createFillBetweenPolygons(xdata, y1, y2, where, pb, \ offset, zdir) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics def text(self, x, y, z, s, zdir=None, **kwargs): """ Add text to the plot. kwargs will be passed on to text, except for the zdir keyword, which sets the direction to be used as the z direction. :param x: (*float*) X coordinate. :param y: (*float*) Y coordinate. :param z: (*float*) Z coordinate. :param s: (*string*) Text string. :param zdir: Z direction. :return: 3D text graphics """ if isinstance(x, (list, tuple)): x = np.array(x) if isinstance(y, (list, tuple)): y = np.array(y) if isinstance(z, (list, tuple)): z = np.array(z) if isinstance(s, (list, tuple)): s = np.array(s) ss = s[0] else: ss = s fontname = kwargs.pop('fontname', 'Arial') 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 = plotutil.getcolor(color) text = ChartText3D() text.setText(ss) text.setFont(font) text.setColor(c) if not isinstance(x, np.NDArray): text.setPoint(x, y, z) ha = kwargs.pop('horizontalalignment', None) if ha is None: ha = kwargs.pop('ha', None) if not ha is None: text.setXAlign(ha) va = kwargs.pop('verticalalignment', None) if va is None: va = kwargs.pop('va', None) if not va is None: text.setYAlign(va) 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 = plotutil.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 = plotutil.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) if not zdir is None: if isinstance(zdir, (list, tuple)): text.setZDir(zdir[0], zdir[1], zdir[2]) else: text.setZDir(zdir) draw3D = kwargs.pop('draw3d', None) if not draw3D is None: text.setDraw3D(draw3D) if isinstance(x, np.NDArray): graphic = GraphicFactory.createTexts3D(x._array, y._array, z._array, s._array, text) else: graphic = Graphic(text, None) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphic) return graphic 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 = self._axes.project(x, y, z) x = r.x y = r.y 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