From 10e92c09f824d91719a15e1bf2093e21904f605b Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Tue, 26 Jan 2016 14:52:54 -0800 Subject: [PATCH 01/22] Made VCSAddon be a new-style object --- Packages/vcsaddons/Lib/core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Packages/vcsaddons/Lib/core.py b/Packages/vcsaddons/Lib/core.py index 38932c4869..b12bf627d0 100644 --- a/Packages/vcsaddons/Lib/core.py +++ b/Packages/vcsaddons/Lib/core.py @@ -1,7 +1,7 @@ import vcsaddons,vcs import numpy -class VCSaddon: +class VCSaddon(object): def __init__(self,name=None,source='default',x=None,template=None): self._saves={} self.g_nslabs=1 @@ -139,14 +139,14 @@ def restore(self,cleanup=True): self._saves={} - def getgm(self,name): + def getgm(self,source="default"): gm = None for nm in vcsaddons.gms[self.g_name].keys(): - if name == nm: + if source == nm: return vcsaddons.gms[self.g_name][nm] if gm is None: - raise "Could not find graphic method %s named: %s" % (self.g_type, name) + raise "Could not find graphic method %s named: %s" % (self.g_type, source) def creategm(self,name,source='default'): return self.__init__(name,source=source,x=self.x,template=self.template) From ffe9cff7445b9d94f5c35021aec22f7d67b9b6d2 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Tue, 26 Jan 2016 14:53:32 -0800 Subject: [PATCH 02/22] Flake8'd --- Packages/vcsaddons/Lib/histograms.py | 95 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index 6e974f2a63..f51a1500b0 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -1,31 +1,35 @@ from core import VCSaddon -import cdms2,MV2,vcs,vcsaddons +import cdms2 +import MV2 +import vcs +import vcsaddons + class Ghg(VCSaddon): - def __init__(self,name=None,source='default',x=None,template = None): - self.g_name='Ghg' - self.g_type='histogram' - VCSaddon.__init__(self,name,source,x,template) + + def __init__(self, name=None, source='default', x=None, template=None): + self.g_name = 'Ghg' + self.g_type = 'histogram' + VCSaddon.__init__(self, name, source, x, template) if source == 'default': - self.fillareastyles = ['solid',] - self.fillareaindices = [1,] - self.fillareacolors = [252,] - self.line = ['solid',] - self.linewidth=[1.0,] - self.linecolors=[241,] + self.fillareastyles = ['solid'] + self.fillareaindices = [1] + self.fillareacolors = [252] + self.line = ['solid'] + self.linewidth = [1.0] + self.linecolors = [241] else: gm = vcsaddons.gms[self.g_name][source] - self.fillareastyle= gm.fillareastyles + self.fillareastyle = gm.fillareastyles self.fillareaindices = gm.fillareaindices self.fillareacolors = gm.fillareacolors self.line = gm.line self.linewidth = gm.linewidth self.linecolors = gm.linecolors - def list(self): print '---------- Histogram (Ghg) member (attribute) listings ----------' - print 'Canvas Mode = ',self.x.mode + print 'Canvas Mode = ', self.x.mode VCSaddon.list(self) print 'fillareastyles = ', self.fillareastyles print 'fillareaindices = ', self.fillareaindices @@ -33,26 +37,25 @@ def list(self): print 'line = ', self.line print 'linewidth = ', self.linewidth print 'linecolors = ', self.linecolors - - - def plot(self,data,template = None, bg=0, x=None): + + def plot(self, data, template=None, bg=0, x=None): if x is None: x = self.x if template is None: template = self.template - elif isinstance(template,str): + elif isinstance(template, str): template = x.gettemplate(template) elif not vcs.istemplate(template): raise "Error did not know what to do with template: %s" % template - - if not isinstance(data,cdms2.tvariable.TransientVariable): - mode= cdms2.getAutoBounds() + + if not isinstance(data, cdms2.tvariable.TransientVariable): + mode = cdms2.getAutoBounds() cdms2.setAutoBounds("on") data = MV2.array(data) data.getAxis(-1).getBounds() cdms2.setAutoBounds(mode) - while data.rank()>1: + while data.rank() > 1: data = data[0] # ok now we have a good x and a good data @@ -61,26 +64,27 @@ def plot(self,data,template = None, bg=0, x=None): # create the primitive fill = x.createfillarea() line = x.createline() - fill.viewport = [template.data.x1,template.data.x2,template.data.y1,template.data.y2] - line.viewport = [template.data.x1,template.data.x2,template.data.y1,template.data.y2] + fill.viewport = [ + template.data.x1, template.data.x2, template.data.y1, template.data.y2] + line.viewport = [ + template.data.x1, template.data.x2, template.data.y1, template.data.y2] axb = data.getAxis(0).getBounds() - xmn,xmx = vcs.minmax(axb) - ymn,ymx = vcs.minmax(data) - - xmn,xmx,ymn,ymx = self.prep_plot(xmn,xmx,ymn,ymx) - - fill.worldcoordinate=[xmn,xmx,ymn,ymx] - line.worldcoordinate=[xmn,xmx,ymn,ymx] - - styles =[] + xmn, xmx = vcs.minmax(axb) + ymn, ymx = vcs.minmax(data) + + xmn, xmx, ymn, ymx = self.prep_plot(xmn, xmx, ymn, ymx) + + fill.worldcoordinate = [xmn, xmx, ymn, ymx] + line.worldcoordinate = [xmn, xmx, ymn, ymx] + + styles = [] cols = [] indices = [] lt = [] - lw =[] + lw = [] lc = [] xs = [] ys = [] - for i in range(nbars): if i < len(self.fillareastyles): @@ -96,21 +100,20 @@ def plot(self,data,template = None, bg=0, x=None): else: indices.append(self.fillareaindices[-1]) if i < len(self.line): - lt.append( self.line[i]) + lt.append(self.line[i]) else: lt.append(self.line[-1]) if i < len(self.linewidth): - lw.append( self.linewidth[i]) + lw.append(self.linewidth[i]) else: lw.append(self.linewidth[-1]) if i < len(self.line): - lc.append( self.linecolors[i]) + lc.append(self.linecolors[i]) else: lc.append(self.linecolors[-1]) - - xs.append( [axb[i][0],axb[i][1],axb[i][1],axb[i][0],axb[i][0]]) - ys.append( [0,0,data[i],data[i],0]) + xs.append([axb[i][0], axb[i][1], axb[i][1], axb[i][0], axb[i][0]]) + ys.append([0, 0, data[i], data[i], 0]) fill.style = styles fill.x = xs @@ -123,13 +126,13 @@ def plot(self,data,template = None, bg=0, x=None): line.type = lt line.width = lw line.color = lc - + fill.list() displays = [] - displays.append(x.plot(fill,bg=bg)) - displays.append(x.plot(line,bg=bg)) + displays.append(x.plot(fill, bg=bg)) + displays.append(x.plot(line, bg=bg)) - x.worldcoordinate = fill.worldcoordinate - dsp = template.plot(data,self,bg=bg) + x.worldcoordinate = fill.worldcoordinate + dsp = template.plot(data, self, bg=bg) for d in dsp: displays.append(d) From 26031e3a24b17a54f5dc6f62d2112f00cbf10148 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Fri, 5 Feb 2016 08:47:54 -0800 Subject: [PATCH 03/22] Made histogram work and display variance; needs to be cleaned up --- Packages/vcsaddons/Lib/core.py | 6 + Packages/vcsaddons/Lib/histograms.py | 161 ++++++++++++++++++--------- 2 files changed, 115 insertions(+), 52 deletions(-) diff --git a/Packages/vcsaddons/Lib/core.py b/Packages/vcsaddons/Lib/core.py index b12bf627d0..c39667bb85 100644 --- a/Packages/vcsaddons/Lib/core.py +++ b/Packages/vcsaddons/Lib/core.py @@ -38,6 +38,7 @@ def __init__(self,name=None,source='default',x=None,template=None): self.datawc_x2=1.e20 self.datawc_y1=1.e20 self.datawc_y2=1.e20 + self.colormap="default" self.xmtics1='*' self.xmtics2='*' self.ymtics1='*' @@ -48,6 +49,8 @@ def __init__(self,name=None,source='default',x=None,template=None): self.yticlabels2='*' self.xaxisconvert= 'linear' self.yaxisconvert= 'linear' + self.color_1 = 16 + self.color_2 = 239 self.legend = None self.projection='linear' else: @@ -58,6 +61,7 @@ def __init__(self,name=None,source='default',x=None,template=None): self.datawc_x2=gm.datawc_x2 self.datawc_y1=gm.datawc_y1 self.datawc_y2=gm.datawc_x2 + self.colormap=gm.colormap self.xmtics1=gm.xmtics1 self.xmtics2=gm.xmtics2 self.ymtics1=gm.ymtics1 @@ -68,6 +72,8 @@ def __init__(self,name=None,source='default',x=None,template=None): self.yticlabels2=gm.yticlabels2 self.xaxisconvert=gm.xaxisconvert self.yaxisconvert= gm.yaxisconvert + self.color_1 = gm.color_1 + self.color_2 = gm.color_2 self.legend = gm.legend self.projection=gm.projection self.name = name diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index f51a1500b0..69c575615c 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -1,6 +1,7 @@ from core import VCSaddon import cdms2 import MV2 +import numpy import vcs import vcsaddons @@ -12,20 +13,22 @@ def __init__(self, name=None, source='default', x=None, template=None): self.g_type = 'histogram' VCSaddon.__init__(self, name, source, x, template) if source == 'default': - self.fillareastyles = ['solid'] - self.fillareaindices = [1] - self.fillareacolors = [252] - self.line = ['solid'] - self.linewidth = [1.0] - self.linecolors = [241] + self.line = [] + self.linewidth = [] + self.linecolors = [] + self.fillareastyles = [] + self.fillareaindices = [] + self.fillareacolors = [] + self.bins = [] else: gm = vcsaddons.gms[self.g_name][source] - self.fillareastyle = gm.fillareastyles - self.fillareaindices = gm.fillareaindices - self.fillareacolors = gm.fillareacolors self.line = gm.line self.linewidth = gm.linewidth self.linecolors = gm.linecolors + self.fillareastyles = gm.fillareastyles + self.fillareaindices = gm.fillareaindices + self.fillareacolors = gm.fillareacolors + self.bins = gm.bins def list(self): print '---------- Histogram (Ghg) member (attribute) listings ----------' @@ -37,6 +40,7 @@ def list(self): print 'line = ', self.line print 'linewidth = ', self.linewidth print 'linecolors = ', self.linecolors + print 'bins = ', self.bins def plot(self, data, template=None, bg=0, x=None): if x is None: @@ -46,20 +50,34 @@ def plot(self, data, template=None, bg=0, x=None): elif isinstance(template, str): template = x.gettemplate(template) elif not vcs.istemplate(template): - raise "Error did not know what to do with template: %s" % template - - if not isinstance(data, cdms2.tvariable.TransientVariable): - mode = cdms2.getAutoBounds() - cdms2.setAutoBounds("on") - data = MV2.array(data) - data.getAxis(-1).getBounds() - cdms2.setAutoBounds(mode) + raise ValueError("Error did not know what to do with template: %s" % template) - while data.rank() > 1: - data = data[0] + # We'll just flatten the data... if they want to be more precise, should pass in more precise data + data = data.flatten().asma() # ok now we have a good x and a good data - nbars = len(data) + if not self.bins: + self.bins = vcs.utils.mkscale(*vcs.minmax(data)) + + data_bins = numpy.digitize(data, self.bins) - 1 + binned = [data[data_bins==i] for i in range(len(self.bins))] + + means = [] + stds = [] + + max_possible_deviance = 0 + + for ind, databin in enumerate(binned): + means.append(databin.mean()) + stds.append(databin.std()) + if len(self.bins) > ind + 1: + max_possible_deviance = max(means[ind] - self.bins[ind], self.bins[ind + 1] - means[ind], max_possible_deviance) + else: + max_possible_deviance = max(means[ind] - self.bins[ind], max_possible_deviance) + + color_values = [std / max_possible_deviance for std in stds] + y_values, _ = numpy.histogram(data, self.bins) + nbars = len(self.bins) - 1 # create the primitive fill = x.createfillarea() @@ -68,9 +86,9 @@ def plot(self, data, template=None, bg=0, x=None): template.data.x1, template.data.x2, template.data.y1, template.data.y2] line.viewport = [ template.data.x1, template.data.x2, template.data.y1, template.data.y2] - axb = data.getAxis(0).getBounds() - xmn, xmx = vcs.minmax(axb) - ymn, ymx = vcs.minmax(data) + + xmn, xmx = vcs.minmax(self.bins) + ymn, ymx = 0, len(data) xmn, xmx, ymn, ymx = self.prep_plot(xmn, xmx, ymn, ymx) @@ -86,34 +104,67 @@ def plot(self, data, template=None, bg=0, x=None): xs = [] ys = [] - for i in range(nbars): - if i < len(self.fillareastyles): - styles.append(self.fillareastyles[i]) - else: - styles.append(self.fillareastyles[-1]) - if i < len(self.fillareacolors): - cols.append(self.fillareacolors[i]) - else: - cols.append(self.fillareacolors[-1]) - if i < len(self.fillareaindices): - indices.append(self.fillareaindices[i]) - else: - indices.append(self.fillareaindices[-1]) - if i < len(self.line): - lt.append(self.line[i]) - else: - lt.append(self.line[-1]) - if i < len(self.linewidth): - lw.append(self.linewidth[i]) - else: - lw.append(self.linewidth[-1]) - if i < len(self.line): - lc.append(self.linecolors[i]) - else: - lc.append(self.linecolors[-1]) + levels = [.1 * i for i in range(11)] - xs.append([axb[i][0], axb[i][1], axb[i][1], axb[i][0], axb[i][0]]) - ys.append([0, 0, data[i], data[i], 0]) + # Extend fillarea and line attrs to levels + if self.fillareastyles: + while len(self.fillareastyles) < len(levels): + self.fillareastyles.append(self.fillareastyles[-1]) + else: + self.fillareastyles = ["solid"] * len(levels) + + if self.fillareacolors: + while len(self.fillareacolors) < len(levels): + self.fillareacolors.append(self.fillareacolors[-1]) + else: + for lev in levels: + self.fillareacolors.append(int((self.color_2 - self.color_1) * lev) + self.color_1) + + if self.fillareaindices: + while len(self.fillareaindices) < len(levels): + self.fillareaindices.append(self.fillareaindices[-1]) + else: + self.fillareaindices = [1] * len(levels) + + if self.line: + while len(self.line) < len(levels): + self.line.append(self.line[-1]) + else: + self.line = ["solid"] * len(levels) + + if self.linewidth: + while len(self.linewidth) < len(levels): + self.linewidth.append(self.linewidth[-1]) + else: + self.linewidth = [1] * len(levels) + + if self.linecolors: + while len(self.linecolors) < len(levels): + self.linecolors.append(self.linecolors[-1]) + else: + self.linecolors = ["black"] * len(levels) + + for i in range(nbars): + # Calculate level for bar + value = color_values[i] + for lev_ind in range(len(levels)): + if levels[lev_ind] > value: + if lev_ind > 0: + lev_ind -= 1 + break + else: + # Shouldn't ever get here since level 0 is 0 + assert False + + styles.append(self.fillareastyles[lev_ind]) + cols.append(self.fillareacolors[lev_ind]) + indices.append(self.fillareaindices[lev_ind]) + lt.append(self.line[lev_ind]) + lw.append(self.linewidth[lev_ind]) + lc.append(self.linecolors[lev_ind]) + + xs.append([self.bins[i], self.bins[i], self.bins[i + 1], self.bins[i + 1]]) + ys.append([0, y_values[i], y_values[i], 0]) fill.style = styles fill.x = xs @@ -121,20 +172,26 @@ def plot(self, data, template=None, bg=0, x=None): fill.style fill.index = indices fill.color = cols + fill.colormap = self.colormap line.x = xs line.y = ys line.type = lt line.width = lw line.color = lc - fill.list() displays = [] displays.append(x.plot(fill, bg=bg)) displays.append(x.plot(line, bg=bg)) x.worldcoordinate = fill.worldcoordinate - dsp = template.plot(data, self, bg=bg) + + x_axis = cdms2.createAxis(self.bins, id="x") + y_axis = cdms2.createAxis(vcs.mkscale(0, len(data)), id="y") + + dsp = template.plot(x, MV2.masked_array(data), self, bg=bg, X=x_axis, Y=y_axis) for d in dsp: displays.append(d) self.restore() + # Ugh, hack + x.backend.renWin.Render() return displays From 53f54dff490bd99b526ae96e49fc3ecc8362a9e5 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Mon, 8 Feb 2016 10:12:14 -0800 Subject: [PATCH 04/22] Adjusted y scale --- Packages/vcsaddons/Lib/histograms.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index 69c575615c..0b7d7de867 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -88,7 +88,8 @@ def plot(self, data, template=None, bg=0, x=None): template.data.x1, template.data.x2, template.data.y1, template.data.y2] xmn, xmx = vcs.minmax(self.bins) - ymn, ymx = 0, len(data) + # Make the y scale be slightly larger than the largest bar + ymn, ymx = 0, max(y_values) * 1.25 xmn, xmx, ymn, ymx = self.prep_plot(xmn, xmx, ymn, ymx) From 510230038dc751a8e6803964b6ab09a0e1d24e0e Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Tue, 9 Feb 2016 12:09:18 -0800 Subject: [PATCH 05/22] Fixed vcsaddons to use display plots correctly --- Packages/vcs/Lib/Canvas.py | 13 ++++++-- Packages/vcs/Lib/displayplot.py | 5 +++- Packages/vcsaddons/Lib/core.py | 44 +++++++++++++++++++++------- Packages/vcsaddons/Lib/histograms.py | 6 ++-- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/Packages/vcs/Lib/Canvas.py b/Packages/vcs/Lib/Canvas.py index 48327f0c0b..cbe877c8ee 100644 --- a/Packages/vcs/Lib/Canvas.py +++ b/Packages/vcs/Lib/Canvas.py @@ -3518,9 +3518,14 @@ def set_convert_labels(copy_mthd, test=0): tp = "boxfill" elif tp in ("xvsy", "xyvsy", "yxvsx", "scatter"): tp = "1d" - gm = vcs.elements[tp][arglist[4]] + if tp in vcsaddons.gms: + gm = vcsaddons.gms[tp][arglist[4]] + arglist[3] = gm + else: + gm = vcs.elements[tp][arglist[4]] if hasattr(gm, "priority") and gm.priority == 0: return + p = self.getprojection(gm.projection) if p.type in round_projections and ( doratio == "0" or doratio[:4] == "auto"): @@ -3729,20 +3734,22 @@ def set_convert_labels(copy_mthd, test=0): del(keyargs["bg"]) if isinstance(arglist[3], vcsaddons.core.VCSaddon): if arglist[1] is None: - dn = arglist[3].plot( + dn = arglist[3].plot_internal( arglist[0], template=arglist[2], bg=bg, x=self, **keyargs) else: - dn = arglist[3].plot( + dn = arglist[3].plot_internal( arglist[0], arglist[1], template=arglist[2], bg=bg, x=self, **keyargs) + self.display_names.append(dn.name) + return dn else: returned_kargs = self.backend.plot(*arglist, **keyargs) if not keyargs.get("donotstoredisplay", False): diff --git a/Packages/vcs/Lib/displayplot.py b/Packages/vcs/Lib/displayplot.py index 1f00450ba1..dd66fac1d1 100755 --- a/Packages/vcs/Lib/displayplot.py +++ b/Packages/vcs/Lib/displayplot.py @@ -25,6 +25,7 @@ # import VCS_validation_functions import vcs +import vcsaddons class Dp(object): @@ -211,7 +212,7 @@ def _getg_type(self): def _setg_type(self, value): value = VCS_validation_functions.checkString(self, 'g_type', value) value = value.lower() - if value not in vcs.elements and value != "text": + if value not in vcs.elements and value != "text" and value not in vcsaddons.gms: raise ValueError( "invalid g_type '%s' must be one of: %s " % (value, vcs.elements.keys())) @@ -259,6 +260,7 @@ def __init__(self, Dp_name, Dp_name_src='default', parent=None): self._g_name = "default" self._array = [] self._continents = 1 + self._continents_line = "default" self.ratio = None else: src = vcs.elements["display"][Dp_name_src] @@ -269,6 +271,7 @@ def __init__(self, Dp_name, Dp_name_src='default', parent=None): self.g_type = src.g_type self.g_name = src.g_name self.continents = src.continents + self.continents_line = src.continents_line self.priority = src.priority self.ratio = src.ratio diff --git a/Packages/vcsaddons/Lib/core.py b/Packages/vcsaddons/Lib/core.py index c39667bb85..8421e247cf 100644 --- a/Packages/vcsaddons/Lib/core.py +++ b/Packages/vcsaddons/Lib/core.py @@ -5,14 +5,14 @@ class VCSaddon(object): def __init__(self,name=None,source='default',x=None,template=None): self._saves={} self.g_nslabs=1 - if not self.g_name in vcsaddons.gms.keys(): - vcsaddons.gms[self.g_name]={} + if not self.g_type in vcsaddons.gms.keys(): + vcsaddons.gms[self.g_type]={} if name is None: cont = True while cont: num= numpy.random.randint(1000) - nm = 'Ghg_'+str(num) - if not nm in vcsaddons.gms[self.g_name].keys(): + nm = self.g_type + '_'+str(num) + if not nm in vcsaddons.gms[self.g_type].keys(): name = nm cont = False @@ -30,7 +30,7 @@ def __init__(self,name=None,source='default',x=None,template=None): else: raise "Error did not know what to do with template: %s" % template - if name in vcsaddons.gms[self.g_name].keys(): + if name in vcsaddons.gms[self.g_type].keys(): raise "Error graphic method %s already exists" % name if source=='default': @@ -54,9 +54,9 @@ def __init__(self,name=None,source='default',x=None,template=None): self.legend = None self.projection='linear' else: - gm = vcsaddons.gms[self.g_name].get(source,None) + gm = vcsaddons.gms[self.g_type].get(source,None) if gm is None: - raise "error could not find graphic method %s (of type %s)" % (source, self.g_name) + raise "error could not find graphic method %s (of type %s)" % (source, self.g_type) self.datawc_x1=gm.datawc_x1 self.datawc_x2=gm.datawc_x2 self.datawc_y1=gm.datawc_y1 @@ -77,7 +77,7 @@ def __init__(self,name=None,source='default',x=None,template=None): self.legend = gm.legend self.projection=gm.projection self.name = name - vcsaddons.gms[self.g_name][name]=self + vcsaddons.gms[self.g_type][name]=self def list(self): @@ -128,6 +128,30 @@ def prep_plot(self,xmn,xmx,ymn,ymx): setattr(self,axes+sec+n,vcs.mklabels(sc)) return xmn,xmx,ymn,ymx + def plot_internal(self, slab=None, slab2=None, template=None, bg=0, x=None, **kwargs): + """ + Used by vcs to properly build a display plot for this graphics method. + """ + if x is None: + x = self.x + + if slab2 is not None: + displays = self.plot(slab, slab2, template, bg, x, **kwargs) + else: + displays = self.plot(slab, template, bg, x, **kwargs) + + for display in displays: + # Remove the display from the canvas + if display.name in x.display_names: + x.display_names.remove(display.name) + nm, src = x.check_name_source(None, "default", "display") + display = vcs.displayplot.Dp(nm) + display.g_name = self.name + display.g_type = self.g_type + display.array = [slab, slab2] + return display + + def save(self,attribute = None): if attribute is not None: self._saves[attribute] = getattr(self,attribute) @@ -147,9 +171,9 @@ def restore(self,cleanup=True): def getgm(self,source="default"): gm = None - for nm in vcsaddons.gms[self.g_name].keys(): + for nm in vcsaddons.gms[self.g_type].keys(): if source == nm: - return vcsaddons.gms[self.g_name][nm] + return vcsaddons.gms[self.g_type][nm] if gm is None: raise "Could not find graphic method %s named: %s" % (self.g_type, source) diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index 0b7d7de867..d0e41c4ed0 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -42,7 +42,7 @@ def list(self): print 'linecolors = ', self.linecolors print 'bins = ', self.bins - def plot(self, data, template=None, bg=0, x=None): + def plot(self, data, template=None, bg=0, x=None, **kwargs): if x is None: x = self.x if template is None: @@ -190,9 +190,11 @@ def plot(self, data, template=None, bg=0, x=None): dsp = template.plot(x, MV2.masked_array(data), self, bg=bg, X=x_axis, Y=y_axis) for d in dsp: - displays.append(d) + if d is not None: + displays.append(d) self.restore() # Ugh, hack x.backend.renWin.Render() + print displays return displays From 577499883890dc9bd70c1924a3e53b011641e613 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Wed, 10 Feb 2016 09:25:41 -0800 Subject: [PATCH 06/22] Added legend, removed print, fixed the attr lengths --- Packages/vcsaddons/Lib/histograms.py | 30 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index d0e41c4ed0..bf314f246f 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -109,41 +109,41 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): # Extend fillarea and line attrs to levels if self.fillareastyles: - while len(self.fillareastyles) < len(levels): + while len(self.fillareastyles) < (len(levels) - 1): self.fillareastyles.append(self.fillareastyles[-1]) else: - self.fillareastyles = ["solid"] * len(levels) + self.fillareastyles = ["solid"] * (len(levels) - 1) if self.fillareacolors: - while len(self.fillareacolors) < len(levels): + while len(self.fillareacolors) < (len(levels) - 1): self.fillareacolors.append(self.fillareacolors[-1]) else: - for lev in levels: + for lev in levels[:-1]: self.fillareacolors.append(int((self.color_2 - self.color_1) * lev) + self.color_1) if self.fillareaindices: - while len(self.fillareaindices) < len(levels): + while len(self.fillareaindices) < (len(levels) - 1): self.fillareaindices.append(self.fillareaindices[-1]) else: - self.fillareaindices = [1] * len(levels) + self.fillareaindices = [1] * (len(levels) - 1) if self.line: - while len(self.line) < len(levels): + while len(self.line) < (len(levels) - 1): self.line.append(self.line[-1]) else: - self.line = ["solid"] * len(levels) + self.line = ["solid"] * (len(levels) - 1) if self.linewidth: - while len(self.linewidth) < len(levels): + while len(self.linewidth) < (len(levels) - 1): self.linewidth.append(self.linewidth[-1]) else: - self.linewidth = [1] * len(levels) + self.linewidth = [1] * (len(levels) - 1) if self.linecolors: - while len(self.linecolors) < len(levels): + while len(self.linecolors) < (len(levels) - 1): self.linecolors.append(self.linecolors[-1]) else: - self.linecolors = ["black"] * len(levels) + self.linecolors = ["black"] * (len(levels) - 1) for i in range(nbars): # Calculate level for bar @@ -193,8 +193,12 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): if d is not None: displays.append(d) + dsp = template.drawColorBar(self.fillareacolors, levels, legend={0: "No Variance", .1:"", .2: "", .3:"", .4:"", .5:"", .6:"", .7:"", .8:"", .9:"", 1: "High Variance"}, x=x) + for d in dsp: + if d is not None: + displays.append(d) + self.restore() # Ugh, hack x.backend.renWin.Render() - print displays return displays From 3af99c72693cb37050c8b842206a8c9aaf308b8d Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Wed, 10 Feb 2016 12:37:42 -0800 Subject: [PATCH 07/22] Finishing touch-ups on histo --- Packages/vcs/Lib/vcs2vtk.py | 46 ++++++++++++++++++++++++++-- Packages/vcsaddons/Lib/histograms.py | 17 +++++----- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/Packages/vcs/Lib/vcs2vtk.py b/Packages/vcs/Lib/vcs2vtk.py index a7b178e898..a7ab029abe 100644 --- a/Packages/vcs/Lib/vcs2vtk.py +++ b/Packages/vcs/Lib/vcs2vtk.py @@ -1880,7 +1880,49 @@ def generateVectorArray(data1, data2, vtk_grid): def vtkIterate(iterator): iterator.InitTraversal() - obj = iterator.GetNextItem() + obj = iterator.GetNextItemAsObject() while obj is not None: yield obj - obj = iterator.GetNextItem() + obj = iterator.GetNextItemAsObject() + + +# transforms [v1,v2] and returns it +# such that it is in the same order +# and has the same middle interval as [gm1, gm2] +def switchAndTranslate(gm1, gm2, v1, v2, wrapModulo): + assert(v1 < v2) + # keep the same middle of the interval + if (wrapModulo): + gmMiddle = float(gm1 + gm2) / 2.0 + half = float(v2 - v1) / 2.0 + v1 = gmMiddle - half + v2 = gmMiddle + half + # if gm margins are increasing and dataset bounds are decreasing + # or the other way around switch them + if ((gm1 - gm2) * (v1 - v2) < 0): + v1, v2 = v2, v1 + return [v1, v2] + + +# TODO: Get rid of this funtion and pass instead: flip and central meridian +# This function can fail for gmbounds -89, -2 where databounds are 89, 0 +# (the cells in the margins have different sizes: 2 and 4) +# +# returns bounds with the same interval size as databounds +# but in the same order and with the same middle interval +# as gmbounds. The middle and the order are used for +# plotting. wrapModule has YWrap, XWrap in degrees, 0 means no wrap +def getBoundsForPlotting(gmbounds, databounds, wrapModulo): + """ Returns the same interval as databounds but it + matches the order and also it keeps the same center interval as gmbounds + So for instance if databounds is -40, 320 and gmbounds is -180, 180 + this function returns + """ + x1gm, x2gm, y1gm, y2gm = gmbounds[:4] + x1, x2, y1, y2 = databounds[:4] + assert (x1 < x2 and y1 < y2) + if not numpy.allclose([x1gm, x2gm], 1.e20): + x1, x2 = switchAndTranslate(x1gm, x2gm, x1, x2, wrapModulo[1] if wrapModulo else None) + if (isinstance(y1gm, numbers.Number) and not numpy.allclose([y1gm, y2gm], 1.e20)): + y1, y2 = switchAndTranslate(y1gm, y2gm, y1, y2, wrapModulo[0] if wrapModulo else None) + return [x1, x2, y1, y2] diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index bf314f246f..3c2b4a033c 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -76,7 +76,7 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): max_possible_deviance = max(means[ind] - self.bins[ind], max_possible_deviance) color_values = [std / max_possible_deviance for std in stds] - y_values, _ = numpy.histogram(data, self.bins) + y_values = [len(databin) for databin in binned] nbars = len(self.bins) - 1 # create the primitive @@ -91,7 +91,7 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): # Make the y scale be slightly larger than the largest bar ymn, ymx = 0, max(y_values) * 1.25 - xmn, xmx, ymn, ymx = self.prep_plot(xmn, xmx, ymn, ymx) + #xmn, xmx, ymn, ymx = self.prep_plot(xmn, xmx, ymn, ymx) fill.worldcoordinate = [xmn, xmx, ymn, ymx] line.worldcoordinate = [xmn, xmx, ymn, ymx] @@ -180,14 +180,12 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): line.width = lw line.color = lc displays = [] - displays.append(x.plot(fill, bg=bg)) - displays.append(x.plot(line, bg=bg)) - - x.worldcoordinate = fill.worldcoordinate x_axis = cdms2.createAxis(self.bins, id="x") y_axis = cdms2.createAxis(vcs.mkscale(0, len(data)), id="y") + displays.append(x.plot(fill, bg=bg, render=False)) + dsp = template.plot(x, MV2.masked_array(data), self, bg=bg, X=x_axis, Y=y_axis) for d in dsp: if d is not None: @@ -198,7 +196,10 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): if d is not None: displays.append(d) + + displays.append(x.plot(line, bg=bg)) + + x.worldcoordinate = fill.worldcoordinate + self.restore() - # Ugh, hack - x.backend.renWin.Render() return displays From 4c0e5d7862e5a8755a6188e0a49b0cccb1486220 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Fri, 12 Feb 2016 08:11:11 -0800 Subject: [PATCH 08/22] Made the axis be labeled correctly --- Packages/vcsaddons/Lib/histograms.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index 3c2b4a033c..60f866492f 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -51,6 +51,16 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): template = x.gettemplate(template) elif not vcs.istemplate(template): raise ValueError("Error did not know what to do with template: %s" % template) + try: + data_name = data.title + except AttributeError: + try: + data_name = data.long_name + except AttributeError: + try: + data_name = data.id + data.units + except AttributeError: + data_name = data.id # We'll just flatten the data... if they want to be more precise, should pass in more precise data data = data.flatten().asma() @@ -181,12 +191,13 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): line.color = lc displays = [] - x_axis = cdms2.createAxis(self.bins, id="x") - y_axis = cdms2.createAxis(vcs.mkscale(0, len(data)), id="y") + x_axis = cdms2.createAxis(self.bins, id=data_name) + y_axis = cdms2.createAxis(vcs.mkscale(0, ymx), id="bin_size") displays.append(x.plot(fill, bg=bg, render=False)) - - dsp = template.plot(x, MV2.masked_array(data), self, bg=bg, X=x_axis, Y=y_axis) + arr = MV2.masked_array(y_values) + arr.setAxis(0, x_axis) + dsp = template.plot(x, arr, self, bg=bg, X=x_axis, Y=y_axis) for d in dsp: if d is not None: displays.append(d) @@ -196,7 +207,6 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): if d is not None: displays.append(d) - displays.append(x.plot(line, bg=bg)) x.worldcoordinate = fill.worldcoordinate From 60d644963a9cdf7a0b4a8467ae9563d1db002166 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Thu, 12 May 2016 13:36:33 -0700 Subject: [PATCH 09/22] Harden histogram a bit --- Packages/vcsaddons/Lib/core.py | 20 +++++----- Packages/vcsaddons/Lib/histograms.py | 58 ++++++++++++++++++++++------ 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/Packages/vcsaddons/Lib/core.py b/Packages/vcsaddons/Lib/core.py index 8421e247cf..d1b49bf116 100644 --- a/Packages/vcsaddons/Lib/core.py +++ b/Packages/vcsaddons/Lib/core.py @@ -20,7 +20,7 @@ def __init__(self,name=None,source='default',x=None,template=None): self.x=vcs.init() else: self.x=x - + if template is None: self.template = self.x.gettemplate() elif isinstance(template,str): @@ -39,10 +39,10 @@ def __init__(self,name=None,source='default',x=None,template=None): self.datawc_y1=1.e20 self.datawc_y2=1.e20 self.colormap="default" - self.xmtics1='*' - self.xmtics2='*' - self.ymtics1='*' - self.ymtics2='*' + self.xmtics1='' + self.xmtics2='' + self.ymtics1='' + self.ymtics2='' self.xticlabels1='*' self.xticlabels2='*' self.yticlabels1='*' @@ -60,7 +60,7 @@ def __init__(self,name=None,source='default',x=None,template=None): self.datawc_x1=gm.datawc_x1 self.datawc_x2=gm.datawc_x2 self.datawc_y1=gm.datawc_y1 - self.datawc_y2=gm.datawc_x2 + self.datawc_y2=gm.datawc_y2 self.colormap=gm.colormap self.xmtics1=gm.xmtics1 self.xmtics2=gm.xmtics2 @@ -78,7 +78,7 @@ def __init__(self,name=None,source='default',x=None,template=None): self.projection=gm.projection self.name = name vcsaddons.gms[self.g_type][name]=self - + def list(self): print 'graphics method = ',self.g_name @@ -103,9 +103,9 @@ def plot(self): raise "Plot function not implemented for graphic method type: %s" % self.g_name def prep_plot(self,xmn,xmx,ymn,ymx): - + self.save() - + if self.datawc_x1!=1.e20: xmn = self.datawc_x1 if self.datawc_x2!=1.e20: @@ -180,4 +180,4 @@ def getgm(self,source="default"): def creategm(self,name,source='default'): return self.__init__(name,source=source,x=self.x,template=self.template) - + diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index 60f866492f..452ac671ef 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -60,31 +60,48 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): try: data_name = data.id + data.units except AttributeError: - data_name = data.id + try: + data_name = data.id + except AttributeError: + data_name = "array" # We'll just flatten the data... if they want to be more precise, should pass in more precise data - data = data.flatten().asma() + if isinstance(data, cdms2.avariable.AbstractVariable): + data = data.asma() + data = data.flatten() # ok now we have a good x and a good data if not self.bins: self.bins = vcs.utils.mkscale(*vcs.minmax(data)) + # Sort the bins + self.bins.sort() + + # Prune duplicates + pruned_bins = [] + for bin in self.bins: + if pruned_bins and numpy.allclose(bin, pruned_bins[-1]): + continue + pruned_bins.append(bin) + self.bins = pruned_bins data_bins = numpy.digitize(data, self.bins) - 1 binned = [data[data_bins==i] for i in range(len(self.bins))] - means = [] stds = [] max_possible_deviance = 0 for ind, databin in enumerate(binned): - means.append(databin.mean()) - stds.append(databin.std()) + if len(databin) > 0: + means.append(databin.mean()) + stds.append(databin.std()) + else: + means.append(0) + stds.append(0) if len(self.bins) > ind + 1: max_possible_deviance = max(means[ind] - self.bins[ind], self.bins[ind + 1] - means[ind], max_possible_deviance) else: max_possible_deviance = max(means[ind] - self.bins[ind], max_possible_deviance) - color_values = [std / max_possible_deviance for std in stds] y_values = [len(databin) for databin in binned] nbars = len(self.bins) - 1 @@ -97,11 +114,27 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): line.viewport = [ template.data.x1, template.data.x2, template.data.y1, template.data.y2] - xmn, xmx = vcs.minmax(self.bins) - # Make the y scale be slightly larger than the largest bar - ymn, ymx = 0, max(y_values) * 1.25 + vcs_min_max = vcs.minmax(self.bins) + if numpy.allclose(self.datawc_x1, 1e20): + xmn = vcs_min_max[0] + else: + xmn = self.datawc_x1 + + if numpy.allclose(self.datawc_x2, 1e20): + xmx = vcs_min_max[1] + else: + xmx = self.datawc_x2 + + if numpy.allclose(self.datawc_y2, 1e20): + # Make the y scale be slightly larger than the largest bar + ymx = max(y_values) * 1.25 + else: + ymx = self.datawc_y2 - #xmn, xmx, ymn, ymx = self.prep_plot(xmn, xmx, ymn, ymx) + if numpy.allclose(self.datawc_y1, 1e20): + ymn = 0 + else: + ymn = self.datawc_y1 fill.worldcoordinate = [xmn, xmx, ymn, ymx] line.worldcoordinate = [xmn, xmx, ymn, ymx] @@ -166,7 +199,8 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): else: # Shouldn't ever get here since level 0 is 0 assert False - + else: + assert False styles.append(self.fillareastyles[lev_ind]) cols.append(self.fillareacolors[lev_ind]) indices.append(self.fillareaindices[lev_ind]) @@ -192,7 +226,7 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): displays = [] x_axis = cdms2.createAxis(self.bins, id=data_name) - y_axis = cdms2.createAxis(vcs.mkscale(0, ymx), id="bin_size") + y_axis = cdms2.createAxis(vcs.mkscale(ymn, ymx), id="bin_size") displays.append(x.plot(fill, bg=bg, render=False)) arr = MV2.masked_array(y_values) From ce13552f749e477e8fa55dc81b6b0d945d52497f Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Mon, 16 May 2016 13:18:22 -0700 Subject: [PATCH 10/22] Added some new tests --- Packages/vcsaddons/Lib/__init__.py | 3 + Packages/vcsaddons/Lib/core.py | 9 +- Packages/vcsaddons/Lib/histograms.py | 53 ++- Packages/vcsaddons/Lib/polar.py | 395 ++++++++++++++++++ testing/vcsaddons/CMakeLists.txt | 24 ++ .../vcs_addons_test_convert_arrays.py | 69 +++ .../vcs_addons_test_histogram_defaults.py | 22 + .../vcs_addons_test_histogram_inherit.py | 62 +++ testing/vcsaddons/vcs_addons_test_polar.py | 28 ++ .../vcs_addons_test_polar_inherit.py | 50 +++ 10 files changed, 692 insertions(+), 23 deletions(-) create mode 100644 Packages/vcsaddons/Lib/polar.py create mode 100644 testing/vcsaddons/vcs_addons_test_convert_arrays.py create mode 100644 testing/vcsaddons/vcs_addons_test_histogram_defaults.py create mode 100644 testing/vcsaddons/vcs_addons_test_histogram_inherit.py create mode 100644 testing/vcsaddons/vcs_addons_test_polar.py create mode 100644 testing/vcsaddons/vcs_addons_test_polar_inherit.py diff --git a/Packages/vcsaddons/Lib/__init__.py b/Packages/vcsaddons/Lib/__init__.py index eadaa435c1..1ba7829455 100644 --- a/Packages/vcsaddons/Lib/__init__.py +++ b/Packages/vcsaddons/Lib/__init__.py @@ -1,5 +1,6 @@ gms = {} import histograms +import polar import EzTemplate import yxvsxfill import continents @@ -10,3 +11,5 @@ def createhistogram(name=None,source='default',x=None,template=None): return histograms.Ghg(name,source=source,x=x,template=template) def createusercontinents(name=None,source="default",x=None,template=None): return continents.Guc(name,source=source,x=x,template=template) +def createpolar(name=None, source="default", x=None, template=None): + return polar.Gpo(name, source=source, x=x, template=template) diff --git a/Packages/vcsaddons/Lib/core.py b/Packages/vcsaddons/Lib/core.py index d1b49bf116..0a75da1257 100644 --- a/Packages/vcsaddons/Lib/core.py +++ b/Packages/vcsaddons/Lib/core.py @@ -54,9 +54,12 @@ def __init__(self,name=None,source='default',x=None,template=None): self.legend = None self.projection='linear' else: - gm = vcsaddons.gms[self.g_type].get(source,None) - if gm is None: - raise "error could not find graphic method %s (of type %s)" % (source, self.g_type) + if isinstance(source, (str, unicode)): + gm = vcsaddons.gms[self.g_type].get(source,None) + if gm is None: + raise "error could not find graphic method %s (of type %s)" % (source, self.g_type) + else: + gm = source self.datawc_x1=gm.datawc_x1 self.datawc_x2=gm.datawc_x2 self.datawc_y1=gm.datawc_y1 diff --git a/Packages/vcsaddons/Lib/histograms.py b/Packages/vcsaddons/Lib/histograms.py index 452ac671ef..0273529cdd 100644 --- a/Packages/vcsaddons/Lib/histograms.py +++ b/Packages/vcsaddons/Lib/histograms.py @@ -21,7 +21,10 @@ def __init__(self, name=None, source='default', x=None, template=None): self.fillareacolors = [] self.bins = [] else: - gm = vcsaddons.gms[self.g_name][source] + if isinstance(source, (str, unicode)): + gm = vcsaddons.gms[self.g_type][source] + else: + gm = source self.line = gm.line self.linewidth = gm.linewidth self.linecolors = gm.linecolors @@ -31,16 +34,16 @@ def __init__(self, name=None, source='default', x=None, template=None): self.bins = gm.bins def list(self): - print '---------- Histogram (Ghg) member (attribute) listings ----------' - print 'Canvas Mode = ', self.x.mode - VCSaddon.list(self) - print 'fillareastyles = ', self.fillareastyles - print 'fillareaindices = ', self.fillareaindices - print 'fillareacolors = ', self.fillareacolors - print 'line = ', self.line - print 'linewidth = ', self.linewidth - print 'linecolors = ', self.linecolors - print 'bins = ', self.bins + print '---------- Histogram (Ghg) member (attribute) listings ----------' # pragma: no cover + print 'Canvas Mode = ', self.x.mode # pragma: no cover + VCSaddon.list(self) # pragma: no cover + print 'fillareastyles = ', self.fillareastyles # pragma: no cover + print 'fillareaindices = ', self.fillareaindices # pragma: no cover + print 'fillareacolors = ', self.fillareacolors # pragma: no cover + print 'line = ', self.line # pragma: no cover + print 'linewidth = ', self.linewidth # pragma: no cover + print 'linecolors = ', self.linecolors # pragma: no cover + print 'bins = ', self.bins # pragma: no cover def plot(self, data, template=None, bg=0, x=None, **kwargs): if x is None: @@ -49,8 +52,8 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): template = self.template elif isinstance(template, str): template = x.gettemplate(template) - elif not vcs.istemplate(template): - raise ValueError("Error did not know what to do with template: %s" % template) + elif not vcs.istemplate(template): # pragma: no cover + raise ValueError("Error did not know what to do with template: %s" % template) # pragma: no cover try: data_name = data.title except AttributeError: @@ -198,9 +201,9 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): break else: # Shouldn't ever get here since level 0 is 0 - assert False + assert False # pragma: no cover else: - assert False + assert False # pragma: no cover styles.append(self.fillareastyles[lev_ind]) cols.append(self.fillareacolors[lev_ind]) indices.append(self.fillareaindices[lev_ind]) @@ -235,11 +238,21 @@ def plot(self, data, template=None, bg=0, x=None, **kwargs): for d in dsp: if d is not None: displays.append(d) - - dsp = template.drawColorBar(self.fillareacolors, levels, legend={0: "No Variance", .1:"", .2: "", .3:"", .4:"", .5:"", .6:"", .7:"", .8:"", .9:"", 1: "High Variance"}, x=x) - for d in dsp: - if d is not None: - displays.append(d) + legend_labels = {0: "No Variance", + .1: "", + .2: "", + .3: "", + .4: "", + .5: "", + .6: "", + .7: "", + .8: "", + .9: "", + 1: "High Variance"} + template.drawColorBar(self.fillareacolors, levels, + legend=legend_labels, x=x, + style=self.fillareastyles, + index=self.fillareaindices) displays.append(x.plot(line, bg=bg)) diff --git a/Packages/vcsaddons/Lib/polar.py b/Packages/vcsaddons/Lib/polar.py new file mode 100644 index 0000000000..27fb738827 --- /dev/null +++ b/Packages/vcsaddons/Lib/polar.py @@ -0,0 +1,395 @@ +import vcs +import numpy +import vcsaddons + +def circle_points(center, radius, points=75, ratio=1): + """ + Generates the coordinates of a circle in x list and y list. + """ + x = [] + y = [] + if ratio > 1: + ymul = ratio + xmul = 1 + else: + xmul = ratio + ymul = 1 + for i in range(points): + x.append(center[0] + xmul * radius * numpy.cos(float(i) / points * numpy.pi * 2)) + y.append(center[1] + ymul * radius * numpy.sin(float(i) / points * numpy.pi * 2)) + x.append(x[0]) + y.append(y[0]) + return x, y + + +def text_orientation_for_angle(theta, source="default"): + """ + Generates a text orientation that will align text to look good depending on quadrant. + """ + # Normalize to [0, 2*pi) + while 0 > theta: + theta += 2 * numpy.pi + while 2 * numpy.pi <= theta: + theta -= 2 * numpy.pi + + if 0 < theta < numpy.pi: + valign = "bottom" + elif 0 == theta or numpy.pi == theta: + valign = "half" + else: + valign = "top" + + if numpy.pi / 2 > theta or numpy.pi * 3 / 2 < theta: + halign = "left" + elif numpy.allclose(numpy.pi / 2, theta) or numpy.allclose(numpy.pi * 3 / 2, theta): + halign = "center" + else: + halign = "right" + + # Build new text table + to = vcs.createtextorientation(source=source) + to.valign = valign + to.halign = halign + return to + + +def convert_arrays(var, theta): + """ + Normalizes valid input options to two lists of lists of values and a list of names. + + Handles: + list/tuple of list/tuples/arrays + (X,N,2) array + (N,2) array + list/tuple, list/tuple + """ + magnitudes = [] + thetas = [] + names = [] + if theta is None: + # var must be list/tuple of arrays or an array + if isinstance(var, (list, tuple)): + for arr in var: + if isinstance(arr, numpy.ndarray): + if len(arr.shape) == 2 and arr.shape[1] == 2: + magnitudes.append(arr[..., 0].tolist()) + thetas.append(arr[..., 1].tolist()) + try: + names.append(arr.id) + except AttributeError: + names.append(None) + else: + raise ValueError("Array is wrong shape; expected 2d array of 2-long elements, got %dd array of %d-long elements." % (len(arr.shape), arr.shape[-1])) + else: + if len(arr) == 2: + # Might be just a pair + if not isinstance(arr[0], (list, tuple)): + magnitudes.append([arr[0]]) + thetas.append([arr[1]]) + names.append(None) + continue + mag_group = [] + theta_group = [] + for val in arr: + if len(val) != 2: + raise ValueError("List is wrong shape; expected list/tuple of 2 element list/tuples, got %s of %d elements." % (type(val).__name__, len(val))) + mag_group.append(val[0]) + theta_group.append(val[1]) + names.append(None) + magnitudes.append(mag_group) + thetas.append(theta_group) + else: + if len(var.shape) == 3: + for i in range(var.shape[0]): + magnitudes.append(var[i, ..., 0].tolist()) + thetas.append(var[i, ..., 1].tolist()) + try: + names.append(var[i].id) + except AttributeError: + names.append(None) + else: + magnitudes = [var[..., 0].tolist()] + thetas = [var[..., 1].tolist()] + try: + names.append(var.id) + except AttributeError: + names.append(None) + else: + magnitudes = [] + if isinstance(var, (list, tuple)): + if isinstance(var[0], (list, tuple, numpy.ndarray)): + magnitudes = [list(v) for v in var] + else: + magnitudes = [var] + elif isinstance(var, numpy.ndarray): + if len(var.shape) == 1: + magnitudes = [list(var)] + elif len(var.shape) == 2: + magnitudes = [list(var[i]) for i in range(var.shape[0])] + else: + raise ValueError("Array is wrong shape; expected 1d array or 2d array, got %dd array." % len(var.shape)) + + thetas = [] + if isinstance(theta, (list, tuple)): + if isinstance(theta[0], (list, tuple, numpy.ndarray)): + thetas = [list(v) for v in theta] + else: + thetas = [theta] + elif isinstance(theta, numpy.ndarray): + if len(theta.shape) == 1: + thetas = [list(theta)] + elif len(theta.shape) == 2: + thetas = [list(theta[i]) for i in range(theta.shape[0])] + else: + raise ValueError("Array is wrong shape; expected 1d array or 2d array, got %dd array." % len(var.shape)) + names = [None] * len(var) + return magnitudes, thetas, names + + +class Gpo(vcsaddons.core.VCSaddon): + def __init__(self, name=None, source="default", x=None, template=None): + self.g_name = "Gpo" + self.g_type = "polar_oned" + super(Gpo, self).__init__(name, source, x, template) + if source == "default": + self.markersizes = [3] + self.markercolors = ["black"] + self.markers = ["dot"] + self.clockwise = False + self.theta_offset = 0 + self.magnitude_ticks = "*" + self.magnitude_tick_angle = 0 + self.theta_tick_count = 6 + self.group_names = [] + # Nice default labels + self.xticlabels1 = { + 0: "0 (2pi)", + numpy.pi / 4: "pi/4", + numpy.pi / 2: "pi/2", + numpy.pi * 3 / 4.: "3pi/4", + numpy.pi: "pi", + numpy.pi * 5 / 4.: "5pi/4", + numpy.pi * 3 / 2.: "3pi/2", + numpy.pi * 7 / 4.: "7pi/4", + } + else: + if isinstance(source, (str, unicode)): + gm = vcsaddons.gms[self.g_type][source] + else: + gm = source + self.markersizes = gm.markersizes + self.markercolors = gm.markercolors + self.markers = gm.markers + self.clockwise = gm.clockwise + self.theta_offset = gm.theta_offset + self.magnitude_ticks = gm.magnitude_ticks + self.magnitude_tick_angle = gm.magnitude_tick_angle + self.theta_tick_count = gm.theta_tick_count + self.group_names = gm.group_names + + def theta_from_value(self, value): + if numpy.allclose((self.datawc_x1, self.datawc_x2), 1e20): + # No scale specified, just use the value as theta + return value + + minval = self.datawc_x1 + maxval = self.datawc_x2 + + pct_val = (value - minval) / float(maxval - minval) + rad_val = numpy.pi * 2 * pct_val + if self.clockwise: + # Reflect the value + rad_val *= -1 + # Adjust by theta_offset + rad_val += self.theta_offset + return rad_val + + def plot(self, var, theta=None, template=None, bg=0, x=None): + """ + Plots a polar plot of your data. + + If var is an ndarray with the second dimension being 2, it will use the first value + as magnitude and the second as theta. + + Otherwise, if theta is provided, it uses var as magnitude and the theta given. + """ + if x is None: + x = self.x + if template is None: + template = self.template + + magnitudes, thetas, names = convert_arrays(var, theta) + + if self.group_names: + names = self.group_names + while len(names) < len(magnitudes): + names.append(None) + + flat_magnitude = [] + for i in magnitudes: + flat_magnitude.extend(i) + flat_theta = [] + for i in thetas: + flat_theta.extend(i) + + canvas = x + + # Determine aspect ratio for plotting the circle + canvas_info = canvas.canvasinfo() + # Calculate aspect ratio of window + window_aspect = canvas_info["width"] / float(canvas_info["height"]) + if window_aspect > 1: + ymul = window_aspect + xmul = 1 + else: + ymul = 1 + xmul = window_aspect + # Use window_aspect to adjust size of template.data + x0, x1 = template.data.x1, template.data.x2 + y0, y1 = template.data.y1, template.data.y2 + + xdiff = abs(x1 - x0) + ydiff = abs(y1 - y0) + + center = x0 + xdiff / 2., y0 + ydiff / 2. + diameter = min(xdiff, ydiff) + radius = diameter / 2. + + # Outer line + if template.box1.priority > 0: + outer = vcs.createline(source=template.box1.line) + x, y = circle_points(center, radius, ratio=window_aspect) + outer.x = x + outer.y = y + canvas.plot(outer, render=False, bg=bg) + + if numpy.allclose((self.datawc_y1, self.datawc_y2), 1e20): + if self.magnitude_ticks == "*": + m_scale = vcs.mkscale(*vcs.minmax(flat_magnitude)) + else: + if isinstance(self.magnitude_ticks, (str, unicode)): + ticks = vcs.elements["list"][self.magnitude_ticks] + else: + ticks = self.magnitude_ticks + m_scale = ticks + else: + m_scale = vcs.mkscale(self.datawc_y1, self.datawc_y2) + + if template.ytic1.priority > 0: + m_ticks = vcs.createline(source=template.ytic1.line) + m_ticks.x = [] + m_ticks.y = [] + + if template.ylabel1.priority > 0: + to = text_orientation_for_angle(self.magnitude_tick_angle, source=template.ylabel1.textorientation) + m_labels = vcs.createtext(Tt_source=template.ylabel1.texttable, To_source=to) + m_labels.x = [] + m_labels.y = [] + m_labels.string = [] + if self.yticlabels1 == "*": + mag_labels = vcs.mklabels(m_scale) + else: + mag_labels = self.yticlabels1 + else: + m_labels = None + + for lev in m_scale: + lev_radius = radius * float(lev) / m_scale[-1] + x, y = circle_points(center, lev_radius, ratio=window_aspect) + if m_labels is not None: + if lev in mag_labels: + m_labels.string.append(mag_labels[lev]) + m_labels.x.append(xmul * lev_radius * numpy.cos(self.magnitude_tick_angle) + center[0]) + m_labels.y.append(ymul * lev_radius * numpy.sin(self.magnitude_tick_angle) + center[1]) + m_ticks.x.append(x) + m_ticks.y.append(y) + + canvas.plot(m_ticks, render=False, bg=bg) + if m_labels is not None: + canvas.plot(m_labels, render=False, bg=bg) + + if template.xtic1.priority > 0: + t_ticks = vcs.createline(source=template.xtic1.line) + t_ticks.x = [] + t_ticks.y = [] + + if self.xticlabels1 == "*": + if numpy.allclose((self.datawc_x1, self.datawc_x2), 1e20): + tick_thetas = list(numpy.arange(0, numpy.pi * 2, numpy.pi / 4)) + tick_labels = {t: str(t) for t in tick_thetas} + else: + d_theta = (self.datawc_x2 - self.datawc_x1) / float(self.theta_tick_count) + tick_thetas = numpy.arange(self.datawc_x1, self.datawc_x2 + .0001, d_theta) + tick_labels = vcs.mklabels(tick_thetas) + else: + tick_thetas = self.xticlabels1.keys() + tick_labels = self.xticlabels1 + + if template.xlabel1.priority > 0: + t_labels = [] + if self.xticlabels1 == "*": + theta_labels = vcs.mklabels(tick_thetas) + else: + theta_labels = self.xticlabels1 + else: + t_labels = None + + for t in tick_thetas: + angle = self.theta_from_value(t) + x0 = center[0] + (xmul * radius * numpy.cos(angle)) + x1 = center[0] + y0 = center[1] + (ymul * radius * numpy.sin(angle)) + y1 = center[1] + if t_labels is not None: + label = vcs.createtext(Tt_source=template.xlabel1.texttable, + To_source=text_orientation_for_angle(angle, source=template.xlabel1.textorientation)) + label.string = [theta_labels[t]] + label.x = [x0] + label.y = [y0] + t_labels.append(label) + t_ticks.x.append([x0, x1]) + t_ticks.y.append([y0, y1]) + canvas.plot(t_ticks, render=False, bg=bg) + if t_labels is not None: + for l in t_labels: + canvas.plot(l, render=False, bg=bg) + + values = vcs.createmarker() + values.type = self.markers + values.size = self.markersizes + values.color = self.markercolors + values.x = [] + values.y = [] + + if template.legend.priority > 0: + # Only labels that are set will show up in the legend + label_count = len(names) - len([i for i in names if i is None]) + labels = vcs.createtext(Tt_source=template.legend.texttable, To_source=template.legend.textorientation) + labels.x = [] + labels.y = [] + labels.string = [] + + for mag, theta, name in zip(magnitudes, thetas, names): + x = [] + y = [] + for m, t in zip(mag, theta): + t = self.theta_from_value(t) + r = (m - m_scale[0]) / float(m_scale[-1] - m_scale[0]) * radius + x.append(xmul * numpy.cos(t) * r + center[0]) + y.append(ymul * numpy.sin(t) * r + center[1]) + + if template.legend.priority > 0 and name is not None: + lx, ly = template.legend.x1, template.legend.y1 + len(labels.x) / float(label_count) * (template.legend.y2 - template.legend.y1) + x.append(lx) + y.append(ly) + labels.x.append(lx + .01) + labels.y.append(ly) + labels.string.append(name) + values.x.append(x) + values.y.append(y) + + if template.legend.priority > 0: + canvas.plot(labels, bg=bg, render=False) + canvas.plot(values, bg=bg) + + return canvas diff --git a/testing/vcsaddons/CMakeLists.txt b/testing/vcsaddons/CMakeLists.txt index 64b8d1755b..06ebff6008 100644 --- a/testing/vcsaddons/CMakeLists.txt +++ b/testing/vcsaddons/CMakeLists.txt @@ -35,6 +35,30 @@ cdat_add_test(vcs_addons_test_EzTemplate_12_plots_spacing ${cdat_SOURCE_DIR}/testing/vcsaddons/test_EzTemplate_12_plots_spacing.py ${BASELINE_DIR}/test_EzTemplate_12_plots_spacing.png ) +cdat_add_test(vcs_addons_test_histogram_defaults + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_histogram_defaults.py + ${BASELINE_DIR}/vcs_addons_test_histogram_defaults.png +) +cdat_add_test(vcs_addons_test_histogram_inherit + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_histogram_inherit.py + ${BASELINE_DIR}/vcs_addons_test_histogram_inherit.png +) +cdat_add_test(vcs_addons_test_polar + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar.py + ${BASELINE_DIR}/vcs_addons_test_polar.png +) +cdat_add_test(vcs_addons_test_polar_inherit + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_inherit.py + ${BASELINE_DIR}/vcs_addons_test_polar_inherit.png +) +cdat_add_test(vcs_addons_test_convert_arrays + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_convert_arrays.py +) if (CDAT_DOWNLOAD_SAMPLE_DATA) cdat_add_test(vcs_addons_EzTemplate_2x2 diff --git a/testing/vcsaddons/vcs_addons_test_convert_arrays.py b/testing/vcsaddons/vcs_addons_test_convert_arrays.py new file mode 100644 index 0000000000..c39bea5133 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_convert_arrays.py @@ -0,0 +1,69 @@ +import vcsaddons +import numpy + +magnitudes = [1, 2, 3, 4] +thetas = [5, 6, 7, 8] +zipped_input = zip(magnitudes, thetas) +grouped_zipped = [zipped_input[:2], zipped_input[2:]] + +one_array = numpy.array(zip(magnitudes, thetas)) +three_d_array = numpy.array(grouped_zipped) +two_arrays = numpy.array(magnitudes), numpy.array(thetas) +two_array_groups = numpy.array([magnitudes[:2], magnitudes[2:]]), numpy.array([thetas[:2], thetas[2:]]) +list_and_array = two_arrays[0], thetas +two_lists = magnitudes, thetas +lists_of_arrays = [two_arrays[0]], [two_arrays[1]] +array_and_list = magnitudes, two_arrays[1] +one_list_tuples = zip(magnitudes, thetas) +one_list_grouped_tuples = [zip(magnitudes[:2], thetas[:2]), zip(magnitudes[2:], thetas[2:])] +one_list_of_arrays = [numpy.array(zip(magnitudes[:2], thetas[:2])), numpy.array(zip(magnitudes[2:], thetas[2:]))] + +def compare(input, expected): + result = vcsaddons.polar.convert_arrays(*input) + print "Checking", result[0:2], "vs", expected + assert result[0] == expected[0] + assert result[1] == expected[1] + +grouped = ([magnitudes[:2], magnitudes[2:]],[thetas[:2], thetas[2:]]) + +compare((one_array, None), ([magnitudes],[thetas])) +compare(two_arrays, ([magnitudes],[thetas])) +compare(two_array_groups, grouped) +three_d_expected = ([[1, 2], [3, 4]], [[5, 6], [7, 8]]) +compare((three_d_array, None), three_d_expected) +compare(list_and_array, ([magnitudes],[thetas])) +compare(two_lists, ([magnitudes],[thetas])) +compare(lists_of_arrays, ([magnitudes],[thetas])) +compare(array_and_list, ([magnitudes],[thetas])) +compare((one_list_tuples, None), ([[i] for i in magnitudes], [[i] for i in thetas])) +compare((one_list_grouped_tuples, None), grouped) +compare((one_list_of_arrays, None), grouped) + + +def test_error(input, error): + try: + vcsaddons.polar.convert_arrays(*input) + except: + print "Got", error + else: + assert False, "Should have raised a %s" % error + +# Test error conditions + +# Single arg: + +# List of 3d arrays +test_error(([numpy.array([[[1, 2]]])], None), "ValueError for list of 3d arrays") +# >2 element arrays +test_error(([numpy.array([[1, 2, 3]])], None), "ValueError for list of 3-element arrays") +# <2 element arrays +test_error(([numpy.array([[1]])], None), "ValueError for list of 1-element arrays") +# Wrong-sized lists +test_error(([[(1, 2, 3)]], None), "ValueError for wrong sized lists.") + + +# Two args: + +# Too many dimensions +test_error((numpy.array([[[1, 2]]]), numpy.array([[1, 2]])), "ValueError for too many dimensions for magnitude.") +test_error((numpy.array([[1, 2]]), numpy.array([[[1, 2]]])), "ValueError for too many dimensions for magnitude.") diff --git a/testing/vcsaddons/vcs_addons_test_histogram_defaults.py b/testing/vcsaddons/vcs_addons_test_histogram_defaults.py new file mode 100644 index 0000000000..b2b19e4997 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_histogram_defaults.py @@ -0,0 +1,22 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +numpy.random.seed(seed=12345) +vals = numpy.random.random_sample(2000) * 100 +histo = vcsaddons.histograms.Ghg() +histo.plot(vals, bg=True, x=x) + +fnm = "vcs_addons_test_histogram_defaults.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_histogram_inherit.py b/testing/vcsaddons/vcs_addons_test_histogram_inherit.py new file mode 100644 index 0000000000..8ce19e0c2c --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_histogram_inherit.py @@ -0,0 +1,62 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs, cdms2 +import vcsaddons, numpy + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") +cdmsfile = cdms2.open(vcs.sample_data + "/clt.nc") +clt = cdmsfile("clt") + +levels = [10, 20, 30, 40, 60, 70, 80, 90, 100] +histo = vcsaddons.histograms.Ghg() +histo.bins = levels +histo.line = ["solid", "dash", "dash-dot"] +histo.linewidth = [1, 2, 3] +histo.linecolors = ["red", "green", "blue"] +histo.fillareastyles = ["solid", "hatch", "pattern", "solid"] +histo.fillareaindices = [1, 2, 3, 4] +histo.fillareacolors = ["blue", "green", "red", "orange"] + +histo2 = vcsaddons.createhistogram(source=histo) + +print "Checking all inherited attributes..." +assert histo2.bins == histo.bins +assert histo2.line == histo.line +assert histo2.linewidth == histo.linewidth +assert histo2.linecolors == histo.linecolors +assert histo2.fillareastyles == histo.fillareastyles +assert histo2.fillareacolors == histo.fillareacolors +assert histo2.fillareaindices == histo.fillareaindices +print "Inherited all values." + +histo2.levels = [10, 20, 10, 100, 110, 50, 20] +histo3 = vcsaddons.createhistogram(source=histo2.name, x=x) + +print "Checking name-based inheritance" +assert histo3.bins == histo2.bins +assert histo3.line == histo2.line +assert histo3.linewidth == histo2.linewidth +assert histo3.linecolors == histo2.linecolors +assert histo3.fillareastyles == histo2.fillareastyles +assert histo3.fillareacolors == histo2.fillareacolors +assert histo3.fillareaindices == histo2.fillareaindices +print "Inherited all values." + +histo3.datawc_y1 = -1 +histo3.datawc_y2 = 200000 +histo3.datawc_x1 = 0 +histo3.datawc_x2 = 100 + +histo3.bins = None +histo3.plot(clt, template="default", bg=True) + +fnm = "vcs_addons_test_histogram_inherit.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_polar.py b/testing/vcsaddons/vcs_addons_test_polar.py new file mode 100644 index 0000000000..8a848e7a1c --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar.py @@ -0,0 +1,28 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +polar = vcsaddons.polar.Gpo() +polar.markers = ["dot", "circle"] +polar.markersizes = [3, 5] + +polar.magnitude_tick_angle = numpy.pi / 6 + +theta = list(numpy.arange(0, 4 * numpy.pi + .01, numpy.pi / 24)) +magnitude = list(numpy.sin(theta)) + +polar.plot(magnitude, theta, bg=True, x=x) + +fnm = "vcs_addons_test_polar.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_polar_inherit.py b/testing/vcsaddons/vcs_addons_test_polar_inherit.py new file mode 100644 index 0000000000..4eb9463593 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar_inherit.py @@ -0,0 +1,50 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +gm = vcsaddons.polar.Gpo() +gm.markers = ["dot", "circle"] +gm.markersizes = [3, 5] +gm.markercolors = ["red", "blue"] +gm.clockwise = True +gm.theta_offset = numpy.pi / 4 +gm.magnitude_ticks = [.2 * i for i in range(6)] +gm.magnitude_tick_angle = numpy.pi / 10 +gm.theta_tick_count = 10 +gm.group_names = ["First", "Second"] + +polar = vcsaddons.polar.Gpo(source=gm) + +assert polar.markersizes == gm.markersizes +assert polar.markercolors == gm.markercolors +assert polar.markers == gm.markers +assert polar.clockwise == gm.clockwise +assert polar.theta_offset == gm.theta_offset +assert polar.magnitude_ticks == gm.magnitude_ticks +assert polar.magnitude_tick_angle == gm.magnitude_tick_angle +assert polar.theta_tick_count == gm.theta_tick_count +assert polar.group_names == gm.group_names + +polar.magnitude_tick_angle = numpy.pi / 6 + +theta = list(numpy.arange(0, 4 * numpy.pi + .01, numpy.pi / 24)) +magnitude = list(numpy.sin(theta)) + +theta = [theta[:len(theta) / 2], theta[len(theta) / 2:]] +magnitude = [magnitude[:len(magnitude)/ 2], magnitude[len(magnitude) / 2:]] + +polar.plot(magnitude, theta, bg=True, x=x) + +fnm = "vcs_addons_test_polar_inherit.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) From a5bc559a3c3e56daafe0a210071ef25a1c87005b Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Thu, 19 May 2016 13:18:50 -0700 Subject: [PATCH 11/22] Fixed some group name retrieval bugs, added colormap support, better secondary management --- Packages/vcsaddons/Lib/polar.py | 57 +++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/Packages/vcsaddons/Lib/polar.py b/Packages/vcsaddons/Lib/polar.py index 27fb738827..8aff589a72 100644 --- a/Packages/vcsaddons/Lib/polar.py +++ b/Packages/vcsaddons/Lib/polar.py @@ -118,14 +118,29 @@ def convert_arrays(var, theta): magnitudes = [] if isinstance(var, (list, tuple)): if isinstance(var[0], (list, tuple, numpy.ndarray)): - magnitudes = [list(v) for v in var] + for v in var: + magnitudes.append(list(v)) + try: + names.append(v.id) + except AttributeError: + names.append(None) else: magnitudes = [var] + names.appned(None) elif isinstance(var, numpy.ndarray): if len(var.shape) == 1: magnitudes = [list(var)] + try: + names.append(var.id) + except AttributeError: + names.append(None) elif len(var.shape) == 2: - magnitudes = [list(var[i]) for i in range(var.shape[0])] + for i in range(var.shape[0]): + magnitudes.append(list(var[i])) + try: + names.append(var[i].id) + except AttributeError: + names.append(None) else: raise ValueError("Array is wrong shape; expected 1d array or 2d array, got %dd array." % len(var.shape)) @@ -142,7 +157,8 @@ def convert_arrays(var, theta): thetas = [list(theta[i]) for i in range(theta.shape[0])] else: raise ValueError("Array is wrong shape; expected 1d array or 2d array, got %dd array." % len(var.shape)) - names = [None] * len(var) + if not names: + names = [None] * len(var) return magnitudes, thetas, names @@ -219,7 +235,6 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): template = self.template magnitudes, thetas, names = convert_arrays(var, theta) - if self.group_names: names = self.group_names while len(names) < len(magnitudes): @@ -233,7 +248,6 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): flat_theta.extend(i) canvas = x - # Determine aspect ratio for plotting the circle canvas_info = canvas.canvasinfo() # Calculate aspect ratio of window @@ -254,14 +268,15 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): center = x0 + xdiff / 2., y0 + ydiff / 2. diameter = min(xdiff, ydiff) radius = diameter / 2. - + plot_kwargs = {"render": False, "bg": bg, "donotstoredisplay": True} # Outer line if template.box1.priority > 0: outer = vcs.createline(source=template.box1.line) x, y = circle_points(center, radius, ratio=window_aspect) outer.x = x outer.y = y - canvas.plot(outer, render=False, bg=bg) + canvas.plot(outer, **plot_kwargs) + del vcs.elements["line"][outer.name] if numpy.allclose((self.datawc_y1, self.datawc_y2), 1e20): if self.magnitude_ticks == "*": @@ -294,7 +309,7 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): m_labels = None for lev in m_scale: - lev_radius = radius * float(lev) / m_scale[-1] + lev_radius = radius * float(lev - m_scale[0]) / (m_scale[-1] - m_scale[0]) x, y = circle_points(center, lev_radius, ratio=window_aspect) if m_labels is not None: if lev in mag_labels: @@ -303,10 +318,11 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): m_labels.y.append(ymul * lev_radius * numpy.sin(self.magnitude_tick_angle) + center[1]) m_ticks.x.append(x) m_ticks.y.append(y) - - canvas.plot(m_ticks, render=False, bg=bg) + canvas.plot(m_ticks, **plot_kwargs) + del vcs.elements["line"][m_ticks.name] if m_labels is not None: - canvas.plot(m_labels, render=False, bg=bg) + canvas.plot(m_labels, **plot_kwargs) + del vcs.elements["textcombined"][m_labels.name] if template.xtic1.priority > 0: t_ticks = vcs.createline(source=template.xtic1.line) @@ -327,10 +343,7 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): if template.xlabel1.priority > 0: t_labels = [] - if self.xticlabels1 == "*": - theta_labels = vcs.mklabels(tick_thetas) - else: - theta_labels = self.xticlabels1 + theta_labels = tick_labels else: t_labels = None @@ -349,15 +362,18 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): t_labels.append(label) t_ticks.x.append([x0, x1]) t_ticks.y.append([y0, y1]) - canvas.plot(t_ticks, render=False, bg=bg) + canvas.plot(t_ticks, **plot_kwargs) + del vcs.elements["line"][t_ticks.name] if t_labels is not None: for l in t_labels: - canvas.plot(l, render=False, bg=bg) + canvas.plot(l, **plot_kwargs) + del vcs.elements["textcombined"][l.name] values = vcs.createmarker() values.type = self.markers values.size = self.markersizes values.color = self.markercolors + values.colormap = self.colormap values.x = [] values.y = [] @@ -389,7 +405,8 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): values.y.append(y) if template.legend.priority > 0: - canvas.plot(labels, bg=bg, render=False) - canvas.plot(values, bg=bg) - + canvas.plot(labels, **plot_kwargs) + del vcs.elements["textcombined"][labels.name] + canvas.plot(values, bg=bg, donotstoredisplay=True) + del vcs.elements["marker"][values.name] return canvas From 0376fde263b24867e86836c86450d97073e9090c Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Fri, 20 May 2016 12:09:12 -0700 Subject: [PATCH 12/22] Moved vcsaddons imports into functions, to prevent circular dependency issues --- Packages/vcs/vcs/Canvas.py | 4 ++-- Packages/vcs/vcs/displayplot.py | 2 +- Packages/vcs/vcs/queries.py | 3 ++- Packages/vcs/vcs/utils.py | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Packages/vcs/vcs/Canvas.py b/Packages/vcs/vcs/Canvas.py index 3289cab046..a7df15f151 100644 --- a/Packages/vcs/vcs/Canvas.py +++ b/Packages/vcs/vcs/Canvas.py @@ -68,7 +68,6 @@ plot_2_1D_options gui_canvas_closed = 0 canvas_closed = 0 -import vcsaddons # noqa import vcs.manageElements # noqa import configurator # noqa from projection import round_projections # noqa @@ -124,7 +123,7 @@ def dictionarytovcslist(dictionary, name): def _determine_arg_list(g_name, actual_args): "Determine what is in the argument list for plotting graphics methods" - + import vcsaddons itemplate_name = 2 igraphics_method = 3 igraphics_option = 4 @@ -2442,6 +2441,7 @@ def __new_elts(self, original, new): return new def __plot(self, arglist, keyargs): + import vcsaddons # This routine has five arguments in arglist from _determine_arg_list # It adds one for bg and passes those on to Canvas.plot as its sixth diff --git a/Packages/vcs/vcs/displayplot.py b/Packages/vcs/vcs/displayplot.py index dd66fac1d1..80638f2260 100755 --- a/Packages/vcs/vcs/displayplot.py +++ b/Packages/vcs/vcs/displayplot.py @@ -25,7 +25,6 @@ # import VCS_validation_functions import vcs -import vcsaddons class Dp(object): @@ -210,6 +209,7 @@ def _getg_type(self): return self._g_type def _setg_type(self, value): + import vcsaddons value = VCS_validation_functions.checkString(self, 'g_type', value) value = value.lower() if value not in vcs.elements and value != "text" and value not in vcsaddons.gms: diff --git a/Packages/vcs/vcs/queries.py b/Packages/vcs/vcs/queries.py index dc4ffa418c..3974ff90a8 100644 --- a/Packages/vcs/vcs/queries.py +++ b/Packages/vcs/vcs/queries.py @@ -44,7 +44,6 @@ import displayplot import projection import vcs -import vcsaddons from error import vcsError @@ -69,6 +68,7 @@ def isgraphicsmethod(gobj): if vcs.isgraphicsmethod(box): box.list() """ + import vcsaddons if (isinstance(gobj, boxfill.Gfb)): return 1 elif (isinstance(gobj, isofill.Gfi)): @@ -134,6 +134,7 @@ def graphicsmethodtype(gobj): print vcs.graphicsmethodtype(ln) # Will print None, because ln is not a # graphics method """ + import vcsaddons if (isinstance(gobj, boxfill.Gfb)): return 'boxfill' elif (isinstance(gobj, isofill.Gfi)): diff --git a/Packages/vcs/vcs/utils.py b/Packages/vcs/vcs/utils.py index 03815f71ac..5c2a645908 100644 --- a/Packages/vcs/vcs/utils.py +++ b/Packages/vcs/vcs/utils.py @@ -20,7 +20,6 @@ import json import os import tempfile -import vcsaddons import cdms2 import genutil import vtk @@ -1621,6 +1620,7 @@ def monotonic(x): def getgraphicsmethod(type, name): + import vcsaddons if type == "default": type = "boxfill" if isinstance(type, vcsaddons.core.VCSaddon): @@ -1635,6 +1635,7 @@ def getgraphicsmethod(type, name): def creategraphicsmethod(gtype, name): + import vcsaddons if gtype in ['isoline', 'Gi']: func = vcs.createisoline elif gtype in ['isofill', 'Gfi']: From 732c8766ffadfed0d8ba5a206293b903ac1cfd68 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Fri, 20 May 2016 12:09:42 -0700 Subject: [PATCH 13/22] Finished polar, added some convenient defaults for it --- Packages/vcsaddons/Lib/__init__.py | 111 +++++++++++++++++++++++++++++ Packages/vcsaddons/Lib/polar.py | 24 +++++-- 2 files changed, 128 insertions(+), 7 deletions(-) diff --git a/Packages/vcsaddons/Lib/__init__.py b/Packages/vcsaddons/Lib/__init__.py index 1ba7829455..c38e5b29e5 100644 --- a/Packages/vcsaddons/Lib/__init__.py +++ b/Packages/vcsaddons/Lib/__init__.py @@ -4,12 +4,123 @@ import EzTemplate import yxvsxfill import continents +import vcs + def createyxvsxfill(name=None,source='default',x=None,template=None): return yxvsxfill.Gyf(name,source=source,x=x,template=template) + + def createhistogram(name=None,source='default',x=None,template=None): return histograms.Ghg(name,source=source,x=x,template=template) + + def createusercontinents(name=None,source="default",x=None,template=None): return continents.Guc(name,source=source,x=x,template=template) + + def createpolar(name=None, source="default", x=None, template=None): return polar.Gpo(name, source=source, x=x, template=template) + + +def getpolar(name=None): + if name in gms["polar_oned"]: + return gms["polar_oned"][name] + raise KeyError("No Polar GM exists with name '%s'" % name) + + +if "polar_oned" not in gms: + # Create nice polar template + try: + t = vcs.createtemplate("polar_oned") + t.data.x1 = .2 + t.data.x2 = .8 + t.data.y1 = .2 + t.data.y2 = .8 + + t.legend.x1 = .85 + t.legend.x2 = 1 + t.legend.y1 = .15 + t.legend.y2 = .85 + + dash = vcs.createline() + dash.type = "dash" + dot = vcs.createline() + dot.type = "dot" + t.xtic1.line = dash + t.ytic1.line = dot + + left_aligned = vcs.createtextorientation() + left_aligned.halign = "left" + left_aligned.valign = "half" + t.legend.textorientation = left_aligned + except vcs.vcsError: + # Template already exists + pass + # Create some nice default polar GMs + degree_polar = createpolar("degrees", template="polar_oned") + degree_polar.datawc_x1 = 0 + degree_polar.datawc_x2 = 360 + degree_polar.xticlabels1 = { + i: str(i) for i in range(0, 360, 45) + } + + clock_24 = createpolar("diurnal", template="polar_oned") + clock_24.datawc_x1 = 0 + clock_24.datawc_x2 = 24 + clock_24.clockwise = True + # 6 AM on the right + clock_24.theta_offset = -6 + clock_24.xticlabels1 = { + i: str(i) for i in range(0, 24, 3) + } + + + clock_24_meridiem = createpolar("diurnal_12_hour", source="diurnal", template="polar_oned") + clock_24_meridiem.xticlabels1 = { + 0: "12 AM", + 3: "3 AM", + 6: "6 AM", + 9: "9 AM", + 12: "12 PM", + 15: "3 PM", + 18: "6 PM", + 21: "9 PM" + } + + clock_12 = createpolar("semidiurnal", source="diurnal", template="polar_oned") + clock_12.datawc_x2 = 12 + clock_12.xticlabels1 = { + i: str(i) for i in range(3, 13, 3) + } + # 3 on the right + clock_12.theta_offset = -3 + + annual_cycle = createpolar("annual_cycle", template="polar_oned") + annual_cycle.datawc_x1 = 1 + annual_cycle.datawc_x2 = 13 + annual_cycle.clockwise = True + annual_cycle.xticlabels1 = { + 1: "Jan", + 2: "Feb", + 3: "Mar", + 4: "Apr", + 5: "May", + 6: "Jun", + 7: "Jul", + 8: "Aug", + 9: "Sep", + 10: "Oct", + 11: "Nov", + 12: "Dec" + } + # Put December on the top + annual_cycle.theta_offset = -2 + + seasonal = createpolar("seasonal", template="polar_oned") + seasonal.datawc_x1 = 0 + seasonal.datawc_x2 = 4 + seasonal.xticlabels1 = {0: "DJF", 1: "MAM", 2: "JJA", 3: "SON"} + seasonal.clockwise = True + # DJF on top + seasonal.theta_offset = -1 diff --git a/Packages/vcsaddons/Lib/polar.py b/Packages/vcsaddons/Lib/polar.py index 8aff589a72..0b0f6a9fcb 100644 --- a/Packages/vcsaddons/Lib/polar.py +++ b/Packages/vcsaddons/Lib/polar.py @@ -126,7 +126,7 @@ def convert_arrays(var, theta): names.append(None) else: magnitudes = [var] - names.appned(None) + names.append(None) elif isinstance(var, numpy.ndarray): if len(var.shape) == 1: magnitudes = [list(var)] @@ -167,6 +167,7 @@ def __init__(self, name=None, source="default", x=None, template=None): self.g_name = "Gpo" self.g_type = "polar_oned" super(Gpo, self).__init__(name, source, x, template) + self.x = None if source == "default": self.markersizes = [3] self.markercolors = ["black"] @@ -203,21 +204,28 @@ def __init__(self, name=None, source="default", x=None, template=None): self.theta_tick_count = gm.theta_tick_count self.group_names = gm.group_names + def magnitude_from_value(self, value, minmax): + if numpy.allclose((self.datawc_y1, self.datawc_y2), 1e20): + min, max = minmax + else: + min, max = self.datawc_y1, self.datawc_y2 + + return (value - min) / float(max - min) + def theta_from_value(self, value): if numpy.allclose((self.datawc_x1, self.datawc_x2), 1e20): # No scale specified, just use the value as theta - return value + return value + self.theta_offset minval = self.datawc_x1 maxval = self.datawc_x2 + offset = self.theta_offset / float(maxval - minval) - pct_val = (value - minval) / float(maxval - minval) + pct_val = (value - minval) / float(maxval - minval) + offset rad_val = numpy.pi * 2 * pct_val if self.clockwise: # Reflect the value rad_val *= -1 - # Adjust by theta_offset - rad_val += self.theta_offset return rad_val def plot(self, var, theta=None, template=None, bg=0, x=None): @@ -230,6 +238,8 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): Otherwise, if theta is provided, it uses var as magnitude and the theta given. """ if x is None: + if self.x is None: + self.x = vcs.init() x = self.x if template is None: template = self.template @@ -309,7 +319,7 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): m_labels = None for lev in m_scale: - lev_radius = radius * float(lev - m_scale[0]) / (m_scale[-1] - m_scale[0]) + lev_radius = radius * self.magnitude_from_value(lev, (m_scale[0], m_scale[-1])) x, y = circle_points(center, lev_radius, ratio=window_aspect) if m_labels is not None: if lev in mag_labels: @@ -390,7 +400,7 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): y = [] for m, t in zip(mag, theta): t = self.theta_from_value(t) - r = (m - m_scale[0]) / float(m_scale[-1] - m_scale[0]) * radius + r = self.magnitude_from_value(m, (m_scale[0], m_scale[-1])) * radius x.append(xmul * numpy.cos(t) * r + center[0]) y.append(ymul * numpy.sin(t) * r + center[1]) From 022a3aa788d39cef37242b3e86cb436214e2b88e Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Fri, 20 May 2016 12:10:07 -0700 Subject: [PATCH 14/22] Added tests for polar --- testing/vcsaddons/CMakeLists.txt | 25 ++++++++ .../vcsaddons/vcs_addons_test_polar_annual.py | 40 +++++++++++++ .../vcs_addons_test_polar_degrees.py | 29 ++++++++++ .../vcs_addons_test_polar_diurnal.py | 44 ++++++++++++++ .../vcs_addons_test_polar_seasonal.py | 58 +++++++++++++++++++ .../vcs_addons_test_polar_semidiurnal.py | 44 ++++++++++++++ 6 files changed, 240 insertions(+) create mode 100644 testing/vcsaddons/vcs_addons_test_polar_annual.py create mode 100644 testing/vcsaddons/vcs_addons_test_polar_degrees.py create mode 100644 testing/vcsaddons/vcs_addons_test_polar_diurnal.py create mode 100644 testing/vcsaddons/vcs_addons_test_polar_seasonal.py create mode 100644 testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py diff --git a/testing/vcsaddons/CMakeLists.txt b/testing/vcsaddons/CMakeLists.txt index 06ebff6008..a0fd4e90be 100644 --- a/testing/vcsaddons/CMakeLists.txt +++ b/testing/vcsaddons/CMakeLists.txt @@ -59,6 +59,31 @@ cdat_add_test(vcs_addons_test_convert_arrays "${PYTHON_EXECUTABLE}" ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_convert_arrays.py ) +cdat_add_test(vcs_addons_test_polar_degrees + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_degrees.py + ${BASELINE_DIR}/vcs_addons_test_polar_degrees.png +) +cdat_add_test(vcs_addons_test_polar_annual + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_annual.py + ${BASELINE_DIR}/vcs_addons_test_polar_annual.png +) +cdat_add_test(vcs_addons_test_polar_diurnal + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_diurnal.py + ${BASELINE_DIR}/vcs_addons_test_polar_diurnal.png +) +cdat_add_test(vcs_addons_test_polar_seasonal + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_seasonal.py + ${BASELINE_DIR}/vcs_addons_test_polar_seasonal.png +) +cdat_add_test(vcs_addons_test_polar_semidiurnal + "${PYTHON_EXECUTABLE}" + ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py + ${BASELINE_DIR}/vcs_addons_test_polar_semidiurnal.png +) if (CDAT_DOWNLOAD_SAMPLE_DATA) cdat_add_test(vcs_addons_EzTemplate_2x2 diff --git a/testing/vcsaddons/vcs_addons_test_polar_annual.py b/testing/vcsaddons/vcs_addons_test_polar_annual.py new file mode 100644 index 0000000000..420b724cda --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar_annual.py @@ -0,0 +1,40 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +polar = vcsaddons.getpolar("annual_cycle") +polar.markers = ["dot"] +polar.markersizes = [3] + +polar.magnitude_tick_angle = numpy.pi / 8 + +import cdms2, cdutil + +f = cdms2.open(os.path.join(vcs.sample_data, "clt.nc")) +clt = f("clt") +cdutil.setAxisTimeBoundsMonthly(clt.getTime()) +averaged_time = cdutil.averager(clt, axis="t") +averaged_time = averaged_time.reshape((1, averaged_time.shape[0], averaged_time.shape[1])) +averaged_time_for_departures = numpy.repeat(averaged_time, len(clt), axis=0) + +clt_departures = clt - averaged_time_for_departures +clt_departures.setAxisList(clt.getAxisList()) +avg_departures = cdutil.averager(clt_departures, axis="xy") + +theta = range(1, len(clt) + 1) +magnitude = avg_departures +polar.plot(magnitude, theta, bg=True, x=x) + +fnm = "vcs_addons_test_polar_annual.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_polar_degrees.py b/testing/vcsaddons/vcs_addons_test_polar_degrees.py new file mode 100644 index 0000000000..46d34168a7 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar_degrees.py @@ -0,0 +1,29 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +polar = vcsaddons.getpolar("degrees") +polar.markers = ["dot", "circle"] +polar.markersizes = [3, 5] + +polar.magnitude_tick_angle = numpy.pi / 6 + +theta = numpy.array(range(0, 720, 2)) +magnitude = 9 * numpy.sin(5 * 2 * numpy.pi * theta / 360) +polar.datawc_y1 = 0 +polar.datawc_y2 = max(magnitude) +polar.plot(magnitude, theta, bg=True, x=x) + +fnm = "vcs_addons_test_polar_degrees.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_polar_diurnal.py b/testing/vcsaddons/vcs_addons_test_polar_diurnal.py new file mode 100644 index 0000000000..ac06641711 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar_diurnal.py @@ -0,0 +1,44 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy +import cdms2, cdutil, cdtime + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +f = cdms2.open(os.path.join(vcs.sample_data, "thermo.nc")) +temp = f('t') +levels = temp.getLevel() +time = temp.getTime() +# Break up temp by level +magnitudes = [temp[:,i] for i in range(temp.shape[1])] +for i, mag in enumerate(magnitudes): + mag.id = "%0.f %s" % (levels[i], levels.units) + +times = [] +for t in time: + reltime = cdtime.relativetime(t, time.units) + comptime = reltime.tocomponent() + times.append(comptime.hour) + +thetas = [times] * len(magnitudes) + +polar = vcsaddons.getpolar("diurnal") +polar.markers = ["dot"] +polar.markersizes = [3] +polar.markercolors = vcs.getcolors(list(levels)) + +polar.magnitude_tick_angle = numpy.pi / 8 + +polar.plot(magnitudes, thetas, bg=True, x=x) + +fnm = "vcs_addons_test_polar_diurnal.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_polar_seasonal.py b/testing/vcsaddons/vcs_addons_test_polar_seasonal.py new file mode 100644 index 0000000000..42612ddae1 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar_seasonal.py @@ -0,0 +1,58 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy, MV2 +import cdms2, cdutil, cdtime + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +f = cdms2.open(os.path.join(vcs.sample_data, "clt.nc")) +# Trim first few months and last month so we have even number of seasons +cloudiness = f('clt', time=(11, 119)) +cdutil.setAxisTimeBoundsMonthly(cloudiness.getTime()) +cloudiness_time_axis = cloudiness.getTime() +averaged_seasons = MV2.zeros((36, 46, 72)) +# Average the seasons in cloudiness +for i in range(36): + averaged_seasons[i] = cdutil.averager(cloudiness(time=(cloudiness_time_axis[i * 3], cloudiness_time_axis[(i+1) * 3])), axis="t") + +averaged_seasons.setAxis(1, cloudiness.getLatitude()) +averaged_seasons.setAxis(2, cloudiness.getLongitude()) + +regions = { + "north_polar": (66, 90), + "north_temperate": (22, 66), + "tropics": (-22, 22), + "south_temperate": (-66, -22), + "south_polar": (-90, -66) +} + +def get_region_avg(var, r, axis="xy"): + avg = cdutil.averager(var(latitude=regions[r]), axis=axis) + avg.id = r + return avg + +magnitudes = [get_region_avg(averaged_seasons, region) for region in regions] +thetas = [range(4) * 27] * 5 + +polar = vcsaddons.getpolar("seasonal") +polar.datawc_y1 = 0 +polar.datawc_y2 = 100 +polar.markers = ["dot"] +polar.markersizes = [3] +polar.markercolors = vcs.getcolors([-90, -66, -22, 22, 66, 90], split=False) + +polar.magnitude_tick_angle = numpy.pi / 4 + +polar.plot(magnitudes, thetas, bg=True, x=x) + +fnm = "vcs_addons_test_polar_seasonal.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) diff --git a/testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py b/testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py new file mode 100644 index 0000000000..900d570b48 --- /dev/null +++ b/testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py @@ -0,0 +1,44 @@ +import sys,os +src = sys.argv[1] +pth = os.path.join(os.path.dirname(__file__),"..") +sys.path.append(pth) +import checkimage +import vcs +import vcsaddons, numpy +import cdms2, cdutil, cdtime + +x=vcs.init() +x.setantialiasing(0) +x.drawlogooff() +x.setbgoutputdimensions(1200,1091,units="pixels") + +f = cdms2.open(os.path.join(vcs.sample_data, "thermo.nc")) +temp = f('t') +levels = temp.getLevel() +time = temp.getTime() +# Break up temp by level +magnitudes = [temp[:,i] for i in range(temp.shape[1])] +for i, mag in enumerate(magnitudes): + mag.id = "%0.f %s" % (levels[i], levels.units) + +times = [] +for t in time: + reltime = cdtime.relativetime(t, time.units) + comptime = reltime.tocomponent() + times.append(comptime.hour % 12) + +thetas = [times] * len(magnitudes) + +polar = vcsaddons.getpolar("semidiurnal") +polar.markers = ["dot"] +polar.markersizes = [3] +polar.markercolors = vcs.getcolors(list(levels)) + +polar.magnitude_tick_angle = numpy.pi / 8 + +polar.plot(magnitudes, thetas, bg=True, x=x) + +fnm = "vcs_addons_test_polar_semidiurnal.png" +x.png(fnm) +ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +sys.exit(ret) From a90268e4337be88ebc69adfcd9aeb12cb9a65e0d Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Tue, 31 May 2016 08:24:36 -0700 Subject: [PATCH 15/22] Fixed memory leak, added mintic --- Packages/vcsaddons/Lib/polar.py | 222 +++++++++++++++++++++++++------- 1 file changed, 173 insertions(+), 49 deletions(-) diff --git a/Packages/vcsaddons/Lib/polar.py b/Packages/vcsaddons/Lib/polar.py index 0b0f6a9fcb..622b0d3a0a 100644 --- a/Packages/vcsaddons/Lib/polar.py +++ b/Packages/vcsaddons/Lib/polar.py @@ -2,6 +2,7 @@ import numpy import vcsaddons + def circle_points(center, radius, points=75, ratio=1): """ Generates the coordinates of a circle in x list and y list. @@ -22,37 +23,6 @@ def circle_points(center, radius, points=75, ratio=1): return x, y -def text_orientation_for_angle(theta, source="default"): - """ - Generates a text orientation that will align text to look good depending on quadrant. - """ - # Normalize to [0, 2*pi) - while 0 > theta: - theta += 2 * numpy.pi - while 2 * numpy.pi <= theta: - theta -= 2 * numpy.pi - - if 0 < theta < numpy.pi: - valign = "bottom" - elif 0 == theta or numpy.pi == theta: - valign = "half" - else: - valign = "top" - - if numpy.pi / 2 > theta or numpy.pi * 3 / 2 < theta: - halign = "left" - elif numpy.allclose(numpy.pi / 2, theta) or numpy.allclose(numpy.pi * 3 / 2, theta): - halign = "center" - else: - halign = "right" - - # Build new text table - to = vcs.createtextorientation(source=source) - to.valign = valign - to.halign = halign - return to - - def convert_arrays(var, theta): """ Normalizes valid input options to two lists of lists of values and a list of names. @@ -172,12 +142,21 @@ def __init__(self, name=None, source="default", x=None, template=None): self.markersizes = [3] self.markercolors = ["black"] self.markers = ["dot"] + self.markercolorsource = "group" self.clockwise = False self.theta_offset = 0 self.magnitude_ticks = "*" + self.magnitude_mintics = None self.magnitude_tick_angle = 0 self.theta_tick_count = 6 self.group_names = [] + self.draw_lines = False + self.connect_groups = False + self.linecolors = ["black"] + self.lines = ["solid"] + self.linewidths = [1] + self.markerpriority = 2 + self.linepriority = 1 # Nice default labels self.xticlabels1 = { 0: "0 (2pi)", @@ -197,12 +176,59 @@ def __init__(self, name=None, source="default", x=None, template=None): self.markersizes = gm.markersizes self.markercolors = gm.markercolors self.markers = gm.markers + self.markercolorsource = gm.markercolorsource + self.markerpriority = gm.markerpriority self.clockwise = gm.clockwise + self.draw_lines = gm.draw_lines + self.linecolors = gm.linecolors + self.linewidths = gm.linewidths + self.linepriority = gm.linepriority + self.lines = gm.lines + self.connect_groups = gm.connect_groups self.theta_offset = gm.theta_offset self.magnitude_ticks = gm.magnitude_ticks + self.magnitude_mintics = gm.magnitude_mintics self.magnitude_tick_angle = gm.magnitude_tick_angle self.theta_tick_count = gm.theta_tick_count self.group_names = gm.group_names + self.to_cleanup = [] + + def create_text(self, tt, to): + tc = vcs.createtext(Tt_source=tt, To_source=to) + self.to_cleanup.append(tc.Tt) + self.to_cleanup.append(tc.To) + return tc + + def text_orientation_for_angle(self, theta, source="default"): + """ + Generates a text orientation that will align text to look good depending on quadrant. + """ + # Normalize to [0, 2*pi) + while 0 > theta: + theta += 2 * numpy.pi + while 2 * numpy.pi <= theta: + theta -= 2 * numpy.pi + + if 0 < theta < numpy.pi: + valign = "bottom" + elif 0 == theta or numpy.pi == theta: + valign = "half" + else: + valign = "top" + + if numpy.pi / 2 > theta or numpy.pi * 3 / 2 < theta: + halign = "left" + elif numpy.allclose(numpy.pi / 2, theta) or numpy.allclose(numpy.pi * 3 / 2, theta): + halign = "center" + else: + halign = "right" + + # Build new text table + to = vcs.createtextorientation(source=source) + to.valign = valign + to.halign = halign + self.to_cleanup.append(to) + return to def magnitude_from_value(self, value, minmax): if numpy.allclose((self.datawc_y1, self.datawc_y2), 1e20): @@ -244,6 +270,9 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): if template is None: template = self.template + if self.markercolorsource.lower() not in ("group", "magnitude", "theta"): + raise ValueError("polar.markercolorsource must be one of: 'group', 'magnitude', 'theta'") + magnitudes, thetas, names = convert_arrays(var, theta) if self.group_names: names = self.group_names @@ -306,8 +335,8 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): m_ticks.y = [] if template.ylabel1.priority > 0: - to = text_orientation_for_angle(self.magnitude_tick_angle, source=template.ylabel1.textorientation) - m_labels = vcs.createtext(Tt_source=template.ylabel1.texttable, To_source=to) + to = self.text_orientation_for_angle(self.magnitude_tick_angle, source=template.ylabel1.textorientation) + m_labels = self.create_text(template.ylabel1.texttable, to) m_labels.x = [] m_labels.y = [] m_labels.string = [] @@ -334,23 +363,40 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): canvas.plot(m_labels, **plot_kwargs) del vcs.elements["textcombined"][m_labels.name] + if template.ymintic1.priority > 0 and self.magnitude_mintics is not None: + mag_mintics = vcs.createline(source=template.ymintic1.line) + mag_mintics.x = [] + mag_mintics.y = [] + + mintics = self.magnitude_mintics + if isinstance(mintics, (str, unicode)): + mintics = vcs.elements["list"][mintics] + + for mag in mintics: + mintic_radius = radius * self.magnitude_from_value(mag, (m_scale[0], m_scale[-1])) + x, y = circle_points(center, mintic_radius, ratio=window_aspect) + mag_mintics.x.append(x) + mag_mintics.y.append(y) + canvas.plot(mag_mintics, **plot_kwargs) + del vcs.elements["line"][mag_mintics.name] + + if self.xticlabels1 == "*": + if numpy.allclose((self.datawc_x1, self.datawc_x2), 1e20): + tick_thetas = list(numpy.arange(0, numpy.pi * 2, numpy.pi / 4)) + tick_labels = {t: str(t) for t in tick_thetas} + else: + d_theta = (self.datawc_x2 - self.datawc_x1) / float(self.theta_tick_count) + tick_thetas = numpy.arange(self.datawc_x1, self.datawc_x2 + .0001, d_theta) + tick_labels = vcs.mklabels(tick_thetas) + else: + tick_thetas = self.xticlabels1.keys() + tick_labels = self.xticlabels1 + if template.xtic1.priority > 0: t_ticks = vcs.createline(source=template.xtic1.line) t_ticks.x = [] t_ticks.y = [] - if self.xticlabels1 == "*": - if numpy.allclose((self.datawc_x1, self.datawc_x2), 1e20): - tick_thetas = list(numpy.arange(0, numpy.pi * 2, numpy.pi / 4)) - tick_labels = {t: str(t) for t in tick_thetas} - else: - d_theta = (self.datawc_x2 - self.datawc_x1) / float(self.theta_tick_count) - tick_thetas = numpy.arange(self.datawc_x1, self.datawc_x2 + .0001, d_theta) - tick_labels = vcs.mklabels(tick_thetas) - else: - tick_thetas = self.xticlabels1.keys() - tick_labels = self.xticlabels1 - if template.xlabel1.priority > 0: t_labels = [] theta_labels = tick_labels @@ -364,8 +410,7 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): y0 = center[1] + (ymul * radius * numpy.sin(angle)) y1 = center[1] if t_labels is not None: - label = vcs.createtext(Tt_source=template.xlabel1.texttable, - To_source=text_orientation_for_angle(angle, source=template.xlabel1.textorientation)) + label = self.create_text(template.xlabel1.texttable, self.text_orientation_for_angle(angle, source=template.xlabel1.textorientation)) label.string = [theta_labels[t]] label.x = [x0] label.y = [y0] @@ -384,17 +429,65 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): values.size = self.markersizes values.color = self.markercolors values.colormap = self.colormap + values.priority = self.markerpriority values.x = [] values.y = [] if template.legend.priority > 0: # Only labels that are set will show up in the legend label_count = len(names) - len([i for i in names if i is None]) - labels = vcs.createtext(Tt_source=template.legend.texttable, To_source=template.legend.textorientation) + labels = self.create_text(template.legend.texttable, template.legend.textorientation) labels.x = [] labels.y = [] labels.string = [] + if self.draw_lines: + line = vcs.createline() + line.x = [] + line.y = [] + line.type = self.lines + line.color = self.linecolors if self.linecolors is not None else self.markercolors + line.width = self.linewidths + line.priority = self.linepriority + + # This is up here because when it's part of the main loop, we can lose "order" of points when we flatten them. + for mag, theta in zip(magnitudes, thetas): + x = [] + y = [] + + for m, t in zip(mag, theta): + t = self.theta_from_value(t) + r = self.magnitude_from_value(m, (m_scale[0], m_scale[-1])) * radius + x.append(xmul * numpy.cos(t) * r + center[0]) + y.append(ymul * numpy.sin(t) * r + center[1]) + + if self.connect_groups: + line.x.extend(x) + line.y.extend(y) + else: + line.x.append(x) + line.y.append(y) + + if self.markercolorsource.lower() in ('magnitude', "theta"): + # Regroup the values using the appropriate metric + + mag_flat = numpy.array(magnitudes).flatten() + theta_flat = numpy.array(thetas).flatten() + + if self.markercolorsource.lower() == "magnitude": + scale = m_scale + vals = mag_flat + else: + scale = theta_ticks + vals = theta_flat + + indices = [numpy.where(numpy.logical_and(vals >= scale[i], vals <= scale[i + 1])) for i in range(len(scale) - 1)] + magnitudes = [mag_flat[inds] for inds in indices] + thetas = [theta_flat[inds] for inds in indices] + names = vcs.mklabels(scale, output="list") + names = [names[i] + " - " + names[i + 1] for i in range(len(names) - 1)] + label_count = len(names) + for mag, theta, name in zip(magnitudes, thetas, names): x = [] y = [] @@ -410,13 +503,44 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): y.append(ly) labels.x.append(lx + .01) labels.y.append(ly) - labels.string.append(name) + labels.string.append(str(name)) values.x.append(x) values.y.append(y) if template.legend.priority > 0: canvas.plot(labels, **plot_kwargs) del vcs.elements["textcombined"][labels.name] + if self.draw_lines: + canvas.plot(line, **plot_kwargs) + del vcs.elements["line"][line.name] + + for el in self.to_cleanup: + if vcs.istexttable(el): + if el.name in vcs.elements["texttable"]: + del vcs.elements["texttable"][el.name] + else: + if el.name in vcs.elements["textorientation"]: + del vcs.elements["textorientation"][el.name] + self.to_cleanup = [] + + # Prune unneeded levels from values + to_prune = [] + for ind, (x, y) in enumerate(zip(values.x, values.y)): + if x and y: + continue + else: + to_prune.append(ind) + + for prune_ind in to_prune[::-1]: + del values.x[prune_ind] + del values.y[prune_ind] + if len(values.color) > prune_ind and len(values.color) > 1: + del values.color[prune_ind] + if len(values.size) > prune_ind and len(values.size) > 1: + del values.size[prune_ind] + if len(values.type) > prune_ind and len(values.type) > 1: + del values.type[prune_ind] + canvas.plot(values, bg=bg, donotstoredisplay=True) del vcs.elements["marker"][values.name] return canvas From b95883e9a640c83ac1a52b156238a72fa493fc8a Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Tue, 31 May 2016 12:03:05 -0700 Subject: [PATCH 16/22] Renamed to match scheme --- testing/vcsaddons/CMakeLists.txt | 38 +++++++++---------- ...s.py => test_vcs_addons_convert_arrays.py} | 0 ... => test_vcs_addons_histogram_defaults.py} | 0 ...y => test_vcs_addons_histogram_inherit.py} | 0 ...test_polar.py => test_vcs_addons_polar.py} | 0 ...ual.py => test_vcs_addons_polar_annual.py} | 0 ...es.py => test_vcs_addons_polar_degrees.py} | 0 ...al.py => test_vcs_addons_polar_diurnal.py} | 0 ...it.py => test_vcs_addons_polar_inherit.py} | 0 ...l.py => test_vcs_addons_polar_seasonal.py} | 0 ...y => test_vcs_addons_polar_semidiurnal.py} | 0 11 files changed, 19 insertions(+), 19 deletions(-) rename testing/vcsaddons/{vcs_addons_test_convert_arrays.py => test_vcs_addons_convert_arrays.py} (100%) rename testing/vcsaddons/{vcs_addons_test_histogram_defaults.py => test_vcs_addons_histogram_defaults.py} (100%) rename testing/vcsaddons/{vcs_addons_test_histogram_inherit.py => test_vcs_addons_histogram_inherit.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar.py => test_vcs_addons_polar.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar_annual.py => test_vcs_addons_polar_annual.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar_degrees.py => test_vcs_addons_polar_degrees.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar_diurnal.py => test_vcs_addons_polar_diurnal.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar_inherit.py => test_vcs_addons_polar_inherit.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar_seasonal.py => test_vcs_addons_polar_seasonal.py} (100%) rename testing/vcsaddons/{vcs_addons_test_polar_semidiurnal.py => test_vcs_addons_polar_semidiurnal.py} (100%) diff --git a/testing/vcsaddons/CMakeLists.txt b/testing/vcsaddons/CMakeLists.txt index a0fd4e90be..d6b382fafb 100644 --- a/testing/vcsaddons/CMakeLists.txt +++ b/testing/vcsaddons/CMakeLists.txt @@ -37,52 +37,52 @@ cdat_add_test(vcs_addons_test_EzTemplate_12_plots_spacing ) cdat_add_test(vcs_addons_test_histogram_defaults "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_histogram_defaults.py - ${BASELINE_DIR}/vcs_addons_test_histogram_defaults.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_histogram_defaults.py + ${BASELINE_DIR}/test_vcs_addons_histogram_defaults.png ) cdat_add_test(vcs_addons_test_histogram_inherit "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_histogram_inherit.py - ${BASELINE_DIR}/vcs_addons_test_histogram_inherit.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_histogram_inherit.py + ${BASELINE_DIR}/test_vcs_addons_histogram_inherit.png ) cdat_add_test(vcs_addons_test_polar "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar.py - ${BASELINE_DIR}/vcs_addons_test_polar.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar.py + ${BASELINE_DIR}/test_vcs_addons_polar.png ) cdat_add_test(vcs_addons_test_polar_inherit "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_inherit.py - ${BASELINE_DIR}/vcs_addons_test_polar_inherit.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar_inherit.py + ${BASELINE_DIR}/test_vcs_addons_polar_inherit.png ) cdat_add_test(vcs_addons_test_convert_arrays "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_convert_arrays.py + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_convert_arrays.py ) cdat_add_test(vcs_addons_test_polar_degrees "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_degrees.py - ${BASELINE_DIR}/vcs_addons_test_polar_degrees.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar_degrees.py + ${BASELINE_DIR}/test_vcs_addons_polar_degrees.png ) cdat_add_test(vcs_addons_test_polar_annual "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_annual.py - ${BASELINE_DIR}/vcs_addons_test_polar_annual.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar_annual.py + ${BASELINE_DIR}/test_vcs_addons_polar_annual.png ) cdat_add_test(vcs_addons_test_polar_diurnal "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_diurnal.py - ${BASELINE_DIR}/vcs_addons_test_polar_diurnal.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar_diurnal.py + ${BASELINE_DIR}/test_vcs_addons_polar_diurnal.png ) cdat_add_test(vcs_addons_test_polar_seasonal "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_seasonal.py - ${BASELINE_DIR}/vcs_addons_test_polar_seasonal.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar_seasonal.py + ${BASELINE_DIR}/test_vcs_addons_polar_seasonal.png ) cdat_add_test(vcs_addons_test_polar_semidiurnal "${PYTHON_EXECUTABLE}" - ${cdat_SOURCE_DIR}/testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py - ${BASELINE_DIR}/vcs_addons_test_polar_semidiurnal.png + ${cdat_SOURCE_DIR}/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py + ${BASELINE_DIR}/test_vcs_addons_polar_semidiurnal.png ) if (CDAT_DOWNLOAD_SAMPLE_DATA) diff --git a/testing/vcsaddons/vcs_addons_test_convert_arrays.py b/testing/vcsaddons/test_vcs_addons_convert_arrays.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_convert_arrays.py rename to testing/vcsaddons/test_vcs_addons_convert_arrays.py diff --git a/testing/vcsaddons/vcs_addons_test_histogram_defaults.py b/testing/vcsaddons/test_vcs_addons_histogram_defaults.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_histogram_defaults.py rename to testing/vcsaddons/test_vcs_addons_histogram_defaults.py diff --git a/testing/vcsaddons/vcs_addons_test_histogram_inherit.py b/testing/vcsaddons/test_vcs_addons_histogram_inherit.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_histogram_inherit.py rename to testing/vcsaddons/test_vcs_addons_histogram_inherit.py diff --git a/testing/vcsaddons/vcs_addons_test_polar.py b/testing/vcsaddons/test_vcs_addons_polar.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar.py rename to testing/vcsaddons/test_vcs_addons_polar.py diff --git a/testing/vcsaddons/vcs_addons_test_polar_annual.py b/testing/vcsaddons/test_vcs_addons_polar_annual.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar_annual.py rename to testing/vcsaddons/test_vcs_addons_polar_annual.py diff --git a/testing/vcsaddons/vcs_addons_test_polar_degrees.py b/testing/vcsaddons/test_vcs_addons_polar_degrees.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar_degrees.py rename to testing/vcsaddons/test_vcs_addons_polar_degrees.py diff --git a/testing/vcsaddons/vcs_addons_test_polar_diurnal.py b/testing/vcsaddons/test_vcs_addons_polar_diurnal.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar_diurnal.py rename to testing/vcsaddons/test_vcs_addons_polar_diurnal.py diff --git a/testing/vcsaddons/vcs_addons_test_polar_inherit.py b/testing/vcsaddons/test_vcs_addons_polar_inherit.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar_inherit.py rename to testing/vcsaddons/test_vcs_addons_polar_inherit.py diff --git a/testing/vcsaddons/vcs_addons_test_polar_seasonal.py b/testing/vcsaddons/test_vcs_addons_polar_seasonal.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar_seasonal.py rename to testing/vcsaddons/test_vcs_addons_polar_seasonal.py diff --git a/testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py b/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py similarity index 100% rename from testing/vcsaddons/vcs_addons_test_polar_semidiurnal.py rename to testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py From 6f7c191de90aa38506a78a28f4447dcbe19d7a88 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Tue, 31 May 2016 12:03:38 -0700 Subject: [PATCH 17/22] Converted to using new testing.regression module --- .../test_vcs_addons_histogram_defaults.py | 13 ++++--------- .../test_vcs_addons_histogram_inherit.py | 14 +++++--------- testing/vcsaddons/test_vcs_addons_polar.py | 13 ++++--------- .../vcsaddons/test_vcs_addons_polar_annual.py | 16 ++++++---------- .../vcsaddons/test_vcs_addons_polar_degrees.py | 15 +++++---------- .../vcsaddons/test_vcs_addons_polar_diurnal.py | 13 ++++--------- .../vcsaddons/test_vcs_addons_polar_inherit.py | 13 ++++--------- .../vcsaddons/test_vcs_addons_polar_seasonal.py | 13 ++++--------- .../test_vcs_addons_polar_semidiurnal.py | 13 ++++--------- 9 files changed, 40 insertions(+), 83 deletions(-) diff --git a/testing/vcsaddons/test_vcs_addons_histogram_defaults.py b/testing/vcsaddons/test_vcs_addons_histogram_defaults.py index b2b19e4997..24af6757b1 100644 --- a/testing/vcsaddons/test_vcs_addons_histogram_defaults.py +++ b/testing/vcsaddons/test_vcs_addons_histogram_defaults.py @@ -1,22 +1,17 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() numpy.random.seed(seed=12345) vals = numpy.random.random_sample(2000) * 100 histo = vcsaddons.histograms.Ghg() histo.plot(vals, bg=True, x=x) -fnm = "vcs_addons_test_histogram_defaults.png" +fnm = "test_vcs_addons_histogram_defaults.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_histogram_inherit.py b/testing/vcsaddons/test_vcs_addons_histogram_inherit.py index 8ce19e0c2c..c761c4e05c 100644 --- a/testing/vcsaddons/test_vcs_addons_histogram_inherit.py +++ b/testing/vcsaddons/test_vcs_addons_histogram_inherit.py @@ -1,15 +1,11 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs, cdms2 import vcsaddons, numpy -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() + cdmsfile = cdms2.open(vcs.sample_data + "/clt.nc") clt = cdmsfile("clt") @@ -56,7 +52,7 @@ histo3.bins = None histo3.plot(clt, template="default", bg=True) -fnm = "vcs_addons_test_histogram_inherit.png" +fnm = "test_vcs_addons_histogram_inherit.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar.py b/testing/vcsaddons/test_vcs_addons_polar.py index 8a848e7a1c..5512d9d52b 100644 --- a/testing/vcsaddons/test_vcs_addons_polar.py +++ b/testing/vcsaddons/test_vcs_addons_polar.py @@ -1,15 +1,10 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() polar = vcsaddons.polar.Gpo() polar.markers = ["dot", "circle"] @@ -22,7 +17,7 @@ polar.plot(magnitude, theta, bg=True, x=x) -fnm = "vcs_addons_test_polar.png" +fnm = "test_vcs_addons_polar.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar_annual.py b/testing/vcsaddons/test_vcs_addons_polar_annual.py index 420b724cda..5cea2bfc10 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_annual.py +++ b/testing/vcsaddons/test_vcs_addons_polar_annual.py @@ -1,15 +1,11 @@ import sys,os -src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +src = sys.argv[1] + +x = regression.init() polar = vcsaddons.getpolar("annual_cycle") polar.markers = ["dot"] @@ -34,7 +30,7 @@ magnitude = avg_departures polar.plot(magnitude, theta, bg=True, x=x) -fnm = "vcs_addons_test_polar_annual.png" +fnm = "test_vcs_addons_polar_annual.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar_degrees.py b/testing/vcsaddons/test_vcs_addons_polar_degrees.py index 46d34168a7..3727dad142 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_degrees.py +++ b/testing/vcsaddons/test_vcs_addons_polar_degrees.py @@ -1,15 +1,10 @@ -import sys,os +import sys src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() polar = vcsaddons.getpolar("degrees") polar.markers = ["dot", "circle"] @@ -23,7 +18,7 @@ polar.datawc_y2 = max(magnitude) polar.plot(magnitude, theta, bg=True, x=x) -fnm = "vcs_addons_test_polar_degrees.png" +fnm = "test_vcs_addons_polar_degrees.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar_diurnal.py b/testing/vcsaddons/test_vcs_addons_polar_diurnal.py index ac06641711..927180e38e 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_diurnal.py +++ b/testing/vcsaddons/test_vcs_addons_polar_diurnal.py @@ -1,16 +1,11 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage import vcs import vcsaddons, numpy import cdms2, cdutil, cdtime +import testing.regression as regression -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "thermo.nc")) temp = f('t') @@ -38,7 +33,7 @@ polar.plot(magnitudes, thetas, bg=True, x=x) -fnm = "vcs_addons_test_polar_diurnal.png" +fnm = "test_vcs_addons_polar_diurnal.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar_inherit.py b/testing/vcsaddons/test_vcs_addons_polar_inherit.py index 4eb9463593..4fc56138db 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_inherit.py +++ b/testing/vcsaddons/test_vcs_addons_polar_inherit.py @@ -1,15 +1,10 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() gm = vcsaddons.polar.Gpo() gm.markers = ["dot", "circle"] @@ -44,7 +39,7 @@ polar.plot(magnitude, theta, bg=True, x=x) -fnm = "vcs_addons_test_polar_inherit.png" +fnm = "test_vcs_addons_polar_inherit.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar_seasonal.py b/testing/vcsaddons/test_vcs_addons_polar_seasonal.py index 42612ddae1..6a6eafd9bf 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_seasonal.py +++ b/testing/vcsaddons/test_vcs_addons_polar_seasonal.py @@ -1,16 +1,11 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy, MV2 import cdms2, cdutil, cdtime -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "clt.nc")) # Trim first few months and last month so we have even number of seasons @@ -52,7 +47,7 @@ def get_region_avg(var, r, axis="xy"): polar.plot(magnitudes, thetas, bg=True, x=x) -fnm = "vcs_addons_test_polar_seasonal.png" +fnm = "test_vcs_addons_polar_seasonal.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) diff --git a/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py b/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py index 900d570b48..3061e8a0dd 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py +++ b/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py @@ -1,16 +1,11 @@ import sys,os src = sys.argv[1] -pth = os.path.join(os.path.dirname(__file__),"..") -sys.path.append(pth) -import checkimage +import testing.regression as regression import vcs import vcsaddons, numpy import cdms2, cdutil, cdtime -x=vcs.init() -x.setantialiasing(0) -x.drawlogooff() -x.setbgoutputdimensions(1200,1091,units="pixels") +x=regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "thermo.nc")) temp = f('t') @@ -38,7 +33,7 @@ polar.plot(magnitudes, thetas, bg=True, x=x) -fnm = "vcs_addons_test_polar_semidiurnal.png" +fnm = "test_vcs_addons_polar_semidiurnal.png" x.png(fnm) -ret = checkimage.check_result_image(fnm, src, checkimage.defaultThreshold) +ret = regression.check_result_image(fnm, src) sys.exit(ret) From 541a590922b6332eb50d9f10a55ddfd19ba6e563 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Wed, 8 Jun 2016 13:43:07 -0400 Subject: [PATCH 18/22] falke8 --- Packages/vcsaddons/Lib/polar.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Packages/vcsaddons/Lib/polar.py b/Packages/vcsaddons/Lib/polar.py index 622b0d3a0a..900b349168 100644 --- a/Packages/vcsaddons/Lib/polar.py +++ b/Packages/vcsaddons/Lib/polar.py @@ -49,7 +49,8 @@ def convert_arrays(var, theta): except AttributeError: names.append(None) else: - raise ValueError("Array is wrong shape; expected 2d array of 2-long elements, got %dd array of %d-long elements." % (len(arr.shape), arr.shape[-1])) + raise ValueError("Array is wrong shape; expected 2d array of 2-long elements," + " got %dd array of %d-long elements." % (len(arr.shape), arr.shape[-1])) else: if len(arr) == 2: # Might be just a pair @@ -62,7 +63,8 @@ def convert_arrays(var, theta): theta_group = [] for val in arr: if len(val) != 2: - raise ValueError("List is wrong shape; expected list/tuple of 2 element list/tuples, got %s of %d elements." % (type(val).__name__, len(val))) + raise ValueError("List is wrong shape; expected list/tuple of 2 element list/tuples," + " got %s of %d elements." % (type(val).__name__, len(val))) mag_group.append(val[0]) theta_group.append(val[1]) names.append(None) @@ -112,7 +114,8 @@ def convert_arrays(var, theta): except AttributeError: names.append(None) else: - raise ValueError("Array is wrong shape; expected 1d array or 2d array, got %dd array." % len(var.shape)) + raise ValueError("Array is wrong shape; expected 1d array or 2d array," + " got %dd array." % len(var.shape)) thetas = [] if isinstance(theta, (list, tuple)): @@ -126,7 +129,8 @@ def convert_arrays(var, theta): elif len(theta.shape) == 2: thetas = [list(theta[i]) for i in range(theta.shape[0])] else: - raise ValueError("Array is wrong shape; expected 1d array or 2d array, got %dd array." % len(var.shape)) + raise ValueError("Array is wrong shape; expected 1d array or 2d array," + " got %dd array." % len(var.shape)) if not names: names = [None] * len(var) return magnitudes, thetas, names @@ -335,7 +339,8 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): m_ticks.y = [] if template.ylabel1.priority > 0: - to = self.text_orientation_for_angle(self.magnitude_tick_angle, source=template.ylabel1.textorientation) + to = self.text_orientation_for_angle(self.magnitude_tick_angle, + source=template.ylabel1.textorientation) m_labels = self.create_text(template.ylabel1.texttable, to) m_labels.x = [] m_labels.y = [] @@ -410,7 +415,9 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): y0 = center[1] + (ymul * radius * numpy.sin(angle)) y1 = center[1] if t_labels is not None: - label = self.create_text(template.xlabel1.texttable, self.text_orientation_for_angle(angle, source=template.xlabel1.textorientation)) + label = self.create_text(template.xlabel1.texttable, + self.text_orientation_for_angle(angle, + source=template.xlabel1.textorientation)) label.string = [theta_labels[t]] label.x = [x0] label.y = [y0] @@ -481,7 +488,8 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): scale = theta_ticks vals = theta_flat - indices = [numpy.where(numpy.logical_and(vals >= scale[i], vals <= scale[i + 1])) for i in range(len(scale) - 1)] + indices = [numpy.where(numpy.logical_and(vals >= scale[i], vals <= scale[i + 1])) + for i in range(len(scale) - 1)] magnitudes = [mag_flat[inds] for inds in indices] thetas = [theta_flat[inds] for inds in indices] names = vcs.mklabels(scale, output="list") @@ -498,7 +506,8 @@ def plot(self, var, theta=None, template=None, bg=0, x=None): y.append(ymul * numpy.sin(t) * r + center[1]) if template.legend.priority > 0 and name is not None: - lx, ly = template.legend.x1, template.legend.y1 + len(labels.x) / float(label_count) * (template.legend.y2 - template.legend.y1) + y_offset = len(labels.x) / float(label_count) * (template.legend.y2 - template.legend.y1) + lx, ly = template.legend.x1, template.legend.y1 + y_offset x.append(lx) y.append(ly) labels.x.append(lx + .01) From b88ea73a81a0536f6219412a953ca775a2a89716 Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Wed, 8 Jun 2016 13:44:49 -0400 Subject: [PATCH 19/22] flake8 tests --- .../vcsaddons/test_vcs_addons_convert_arrays.py | 15 ++++++++------- .../test_vcs_addons_histogram_defaults.py | 2 +- .../test_vcs_addons_histogram_inherit.py | 2 +- testing/vcsaddons/test_vcs_addons_polar.py | 2 +- .../vcsaddons/test_vcs_addons_polar_degrees.py | 2 +- .../vcsaddons/test_vcs_addons_polar_diurnal.py | 2 +- .../vcsaddons/test_vcs_addons_polar_inherit.py | 2 +- .../vcsaddons/test_vcs_addons_polar_seasonal.py | 2 +- .../test_vcs_addons_polar_semidiurnal.py | 2 +- 9 files changed, 16 insertions(+), 15 deletions(-) diff --git a/testing/vcsaddons/test_vcs_addons_convert_arrays.py b/testing/vcsaddons/test_vcs_addons_convert_arrays.py index c39bea5133..6e784e10b8 100644 --- a/testing/vcsaddons/test_vcs_addons_convert_arrays.py +++ b/testing/vcsaddons/test_vcs_addons_convert_arrays.py @@ -18,23 +18,24 @@ one_list_grouped_tuples = [zip(magnitudes[:2], thetas[:2]), zip(magnitudes[2:], thetas[2:])] one_list_of_arrays = [numpy.array(zip(magnitudes[:2], thetas[:2])), numpy.array(zip(magnitudes[2:], thetas[2:]))] + def compare(input, expected): result = vcsaddons.polar.convert_arrays(*input) print "Checking", result[0:2], "vs", expected assert result[0] == expected[0] assert result[1] == expected[1] -grouped = ([magnitudes[:2], magnitudes[2:]],[thetas[:2], thetas[2:]]) +grouped = ([magnitudes[:2], magnitudes[2:]], [thetas[:2], thetas[2:]]) -compare((one_array, None), ([magnitudes],[thetas])) -compare(two_arrays, ([magnitudes],[thetas])) +compare((one_array, None), ([magnitudes], [thetas])) +compare(two_arrays, ([magnitudes], [thetas])) compare(two_array_groups, grouped) three_d_expected = ([[1, 2], [3, 4]], [[5, 6], [7, 8]]) compare((three_d_array, None), three_d_expected) -compare(list_and_array, ([magnitudes],[thetas])) -compare(two_lists, ([magnitudes],[thetas])) -compare(lists_of_arrays, ([magnitudes],[thetas])) -compare(array_and_list, ([magnitudes],[thetas])) +compare(list_and_array, ([magnitudes], [thetas])) +compare(two_lists, ([magnitudes], [thetas])) +compare(lists_of_arrays, ([magnitudes], [thetas])) +compare(array_and_list, ([magnitudes], [thetas])) compare((one_list_tuples, None), ([[i] for i in magnitudes], [[i] for i in thetas])) compare((one_list_grouped_tuples, None), grouped) compare((one_list_of_arrays, None), grouped) diff --git a/testing/vcsaddons/test_vcs_addons_histogram_defaults.py b/testing/vcsaddons/test_vcs_addons_histogram_defaults.py index 24af6757b1..090aaf33d8 100644 --- a/testing/vcsaddons/test_vcs_addons_histogram_defaults.py +++ b/testing/vcsaddons/test_vcs_addons_histogram_defaults.py @@ -4,7 +4,7 @@ import vcs import vcsaddons, numpy -x=regression.init() +x = regression.init() numpy.random.seed(seed=12345) vals = numpy.random.random_sample(2000) * 100 diff --git a/testing/vcsaddons/test_vcs_addons_histogram_inherit.py b/testing/vcsaddons/test_vcs_addons_histogram_inherit.py index c761c4e05c..a977a68bbe 100644 --- a/testing/vcsaddons/test_vcs_addons_histogram_inherit.py +++ b/testing/vcsaddons/test_vcs_addons_histogram_inherit.py @@ -4,7 +4,7 @@ import vcs, cdms2 import vcsaddons, numpy -x=regression.init() +x = regression.init() cdmsfile = cdms2.open(vcs.sample_data + "/clt.nc") clt = cdmsfile("clt") diff --git a/testing/vcsaddons/test_vcs_addons_polar.py b/testing/vcsaddons/test_vcs_addons_polar.py index 5512d9d52b..5fcdc6c952 100644 --- a/testing/vcsaddons/test_vcs_addons_polar.py +++ b/testing/vcsaddons/test_vcs_addons_polar.py @@ -4,7 +4,7 @@ import vcs import vcsaddons, numpy -x=regression.init() +x = regression.init() polar = vcsaddons.polar.Gpo() polar.markers = ["dot", "circle"] diff --git a/testing/vcsaddons/test_vcs_addons_polar_degrees.py b/testing/vcsaddons/test_vcs_addons_polar_degrees.py index 3727dad142..1a44b6b0e6 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_degrees.py +++ b/testing/vcsaddons/test_vcs_addons_polar_degrees.py @@ -4,7 +4,7 @@ import vcs import vcsaddons, numpy -x=regression.init() +x = regression.init() polar = vcsaddons.getpolar("degrees") polar.markers = ["dot", "circle"] diff --git a/testing/vcsaddons/test_vcs_addons_polar_diurnal.py b/testing/vcsaddons/test_vcs_addons_polar_diurnal.py index 927180e38e..24a6f832bc 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_diurnal.py +++ b/testing/vcsaddons/test_vcs_addons_polar_diurnal.py @@ -5,7 +5,7 @@ import cdms2, cdutil, cdtime import testing.regression as regression -x=regression.init() +x = regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "thermo.nc")) temp = f('t') diff --git a/testing/vcsaddons/test_vcs_addons_polar_inherit.py b/testing/vcsaddons/test_vcs_addons_polar_inherit.py index 4fc56138db..2eb10b7d8d 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_inherit.py +++ b/testing/vcsaddons/test_vcs_addons_polar_inherit.py @@ -4,7 +4,7 @@ import vcs import vcsaddons, numpy -x=regression.init() +x = regression.init() gm = vcsaddons.polar.Gpo() gm.markers = ["dot", "circle"] diff --git a/testing/vcsaddons/test_vcs_addons_polar_seasonal.py b/testing/vcsaddons/test_vcs_addons_polar_seasonal.py index 6a6eafd9bf..0f5693a35f 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_seasonal.py +++ b/testing/vcsaddons/test_vcs_addons_polar_seasonal.py @@ -5,7 +5,7 @@ import vcsaddons, numpy, MV2 import cdms2, cdutil, cdtime -x=regression.init() +x = regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "clt.nc")) # Trim first few months and last month so we have even number of seasons diff --git a/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py b/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py index 3061e8a0dd..1ce3f21efa 100644 --- a/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py +++ b/testing/vcsaddons/test_vcs_addons_polar_semidiurnal.py @@ -5,7 +5,7 @@ import vcsaddons, numpy import cdms2, cdutil, cdtime -x=regression.init() +x = regression.init() f = cdms2.open(os.path.join(vcs.sample_data, "thermo.nc")) temp = f('t') From 64f378e20839dde709c8668d09acae7a415cc857 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Fri, 10 Jun 2016 21:44:01 -0400 Subject: [PATCH 20/22] Fixed style issues --- Packages/vcs/vcs/Canvas.py | 1 - Packages/vcs/vcs/dv3d.py | 1 - 2 files changed, 2 deletions(-) diff --git a/Packages/vcs/vcs/Canvas.py b/Packages/vcs/vcs/Canvas.py index eb774505bc..8ef04cd8e1 100644 --- a/Packages/vcs/vcs/Canvas.py +++ b/Packages/vcs/vcs/Canvas.py @@ -4920,7 +4920,6 @@ def _compute_width_height(self, width, height, units, ps=False): H = tmp return W, H - def postscript(self, file, mode='r', orientation=None, width=None, height=None, units='inches', textAsPaths=True): """ diff --git a/Packages/vcs/vcs/dv3d.py b/Packages/vcs/vcs/dv3d.py index 2afae29f2c..4a30aed8e6 100644 --- a/Packages/vcs/vcs/dv3d.py +++ b/Packages/vcs/vcs/dv3d.py @@ -158,7 +158,6 @@ def __init__(self, Gfdv3d_name, Gfdv3d_name_src='default'): self.plot_attributes['name'] = self.g_name self.plot_attributes['template'] = Gfdv3d_name - def setProvenanceHandler(self, provenanceHandler): self.provenanceHandler = provenanceHandler From fb306a36006b7406460649306d2edb339939a7da Mon Sep 17 00:00:00 2001 From: Sam Fries Date: Fri, 10 Jun 2016 11:05:39 -0400 Subject: [PATCH 21/22] Fixed failing tests --- Packages/vcs/vcs/Canvas.py | 12 ++++++------ Packages/vcsaddons/Lib/__init__.py | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Packages/vcs/vcs/Canvas.py b/Packages/vcs/vcs/Canvas.py index 8ef04cd8e1..903e22a7a0 100644 --- a/Packages/vcs/vcs/Canvas.py +++ b/Packages/vcs/vcs/Canvas.py @@ -2450,13 +2450,13 @@ def __new_elts(self, original, new): def __plot(self, arglist, keyargs): import vcsaddons - # This routine has five arguments in arglist from _determine_arg_list - # It adds one for bg and passes those on to Canvas.plot as its sixth - # arguments. + # This routine has five arguments in arglist from _determine_arg_list + # It adds one for bg and passes those on to Canvas.plot as its sixth + # arguments. - # First of all let's remember which elets we have before comin in here - # so that anything added (temp objects) can be removed at clear - # time + # First of all let's remember which elets we have before comin in here + # so that anything added (temp objects) can be removed at clear + # time original_elts = {} new_elts = {} for k in vcs.elements.keys(): diff --git a/Packages/vcsaddons/Lib/__init__.py b/Packages/vcsaddons/Lib/__init__.py index c38e5b29e5..7136d36aa3 100644 --- a/Packages/vcsaddons/Lib/__init__.py +++ b/Packages/vcsaddons/Lib/__init__.py @@ -20,16 +20,20 @@ def createusercontinents(name=None,source="default",x=None,template=None): def createpolar(name=None, source="default", x=None, template=None): + if "polar_oned" not in gms: + init_polar() return polar.Gpo(name, source=source, x=x, template=template) def getpolar(name=None): + if "polar_oned" not in gms: + init_polar() if name in gms["polar_oned"]: return gms["polar_oned"][name] raise KeyError("No Polar GM exists with name '%s'" % name) -if "polar_oned" not in gms: +def init_polar(): # Create nice polar template try: t = vcs.createtemplate("polar_oned") @@ -58,14 +62,14 @@ def getpolar(name=None): # Template already exists pass # Create some nice default polar GMs - degree_polar = createpolar("degrees", template="polar_oned") + degree_polar = polar.Gpo("degrees", template="polar_oned") degree_polar.datawc_x1 = 0 degree_polar.datawc_x2 = 360 degree_polar.xticlabels1 = { i: str(i) for i in range(0, 360, 45) } - clock_24 = createpolar("diurnal", template="polar_oned") + clock_24 = polar.Gpo("diurnal", template="polar_oned") clock_24.datawc_x1 = 0 clock_24.datawc_x2 = 24 clock_24.clockwise = True @@ -75,8 +79,7 @@ def getpolar(name=None): i: str(i) for i in range(0, 24, 3) } - - clock_24_meridiem = createpolar("diurnal_12_hour", source="diurnal", template="polar_oned") + clock_24_meridiem = polar.Gpo("diurnal_12_hour", source="diurnal", template="polar_oned") clock_24_meridiem.xticlabels1 = { 0: "12 AM", 3: "3 AM", @@ -88,7 +91,7 @@ def getpolar(name=None): 21: "9 PM" } - clock_12 = createpolar("semidiurnal", source="diurnal", template="polar_oned") + clock_12 = polar.Gpo("semidiurnal", source="diurnal", template="polar_oned") clock_12.datawc_x2 = 12 clock_12.xticlabels1 = { i: str(i) for i in range(3, 13, 3) @@ -96,7 +99,7 @@ def getpolar(name=None): # 3 on the right clock_12.theta_offset = -3 - annual_cycle = createpolar("annual_cycle", template="polar_oned") + annual_cycle = polar.Gpo("annual_cycle", template="polar_oned") annual_cycle.datawc_x1 = 1 annual_cycle.datawc_x2 = 13 annual_cycle.clockwise = True @@ -117,7 +120,7 @@ def getpolar(name=None): # Put December on the top annual_cycle.theta_offset = -2 - seasonal = createpolar("seasonal", template="polar_oned") + seasonal = polar.Gpo("seasonal", template="polar_oned") seasonal.datawc_x1 = 0 seasonal.datawc_x2 = 4 seasonal.xticlabels1 = {0: "DJF", 1: "MAM", 2: "JJA", 3: "SON"} From c0ddfc13049d04ea48e81e49b753b3df28be1e28 Mon Sep 17 00:00:00 2001 From: Aashish Chaudhary Date: Sat, 11 Jun 2016 12:47:23 -0400 Subject: [PATCH 22/22] Fixed another failing test --- testing/vcs/test_vcs_read_old_scr.py | 1 + 1 file changed, 1 insertion(+) diff --git a/testing/vcs/test_vcs_read_old_scr.py b/testing/vcs/test_vcs_read_old_scr.py index 0a61df61e5..4ae04d8491 100644 --- a/testing/vcs/test_vcs_read_old_scr.py +++ b/testing/vcs/test_vcs_read_old_scr.py @@ -71,3 +71,4 @@ assert(gm.ymtics1=="lat5") assert(gm.fillareastyle == "solid") assert(gm.fillareacolors == [30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 35, 36]) +sys.exit(0)