You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@climate.apache.org by ah...@apache.org on 2013/08/19 23:43:45 UTC
svn commit: r1515622 -
/incubator/climate/branches/RefactorPlots/rcmet/src/main/python/rcmes/utils/taylor.py
Author: ahart
Date: Mon Aug 19 21:43:45 2013
New Revision: 1515622
URL: http://svn.apache.org/r1515622
Log:
CLIMATE-259: add utility class for generating taylor diagrams
Added:
incubator/climate/branches/RefactorPlots/rcmet/src/main/python/rcmes/utils/taylor.py
Added: incubator/climate/branches/RefactorPlots/rcmet/src/main/python/rcmes/utils/taylor.py
URL: http://svn.apache.org/viewvc/incubator/climate/branches/RefactorPlots/rcmet/src/main/python/rcmes/utils/taylor.py?rev=1515622&view=auto
==============================================================================
--- incubator/climate/branches/RefactorPlots/rcmet/src/main/python/rcmes/utils/taylor.py (added)
+++ incubator/climate/branches/RefactorPlots/rcmet/src/main/python/rcmes/utils/taylor.py Mon Aug 19 21:43:45 2013
@@ -0,0 +1,144 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+"""
+Taylor diagram (Taylor, 2001) test implementation.
+
+http://www-pcmdi.llnl.gov/about/staff/Taylor/CV/Taylor_diagram_primer.htm
+"""
+
+__version__ = "Time-stamp: <2012-02-17 20:59:35 ycopin>"
+__author__ = "Yannick Copin <ya...@laposte.net>"
+
+import numpy as NP
+import matplotlib.pyplot as PLT
+
+class TaylorDiagram(object):
+ """Taylor diagram: plot model standard deviation and correlation
+ to reference (data) sample in a single-quadrant polar plot, with
+ r=stddev and theta=arccos(correlation).
+ """
+
+ def __init__(self, refstd, radmax=1.5, fig=None, rect=111, label='_'):
+ """Set up Taylor diagram axes, i.e. single quadrant polar
+ plot, using mpl_toolkits.axisartist.floating_axes. refstd is
+ the reference standard deviation to be compared to.
+ """
+
+ from matplotlib.projections import PolarAxes
+ import mpl_toolkits.axisartist.floating_axes as FA
+ import mpl_toolkits.axisartist.grid_finder as GF
+
+ self.refstd = refstd # Reference standard deviation
+
+ tr = PolarAxes.PolarTransform()
+
+ # Correlation labels
+ rlocs = NP.concatenate((NP.arange(10)/10.,[0.95,0.99]))
+ tlocs = NP.arccos(rlocs) # Conversion to polar angles
+ gl1 = GF.FixedLocator(tlocs) # Positions
+ tf1 = GF.DictFormatter(dict(zip(tlocs, map(str,rlocs))))
+
+ # Standard deviation axis extent
+ self.smin = 0
+ self.smax = radmax*self.refstd
+
+ ghelper = FA.GridHelperCurveLinear(tr,
+ extremes=(0,NP.pi/2, # 1st quadrant
+ self.smin,self.smax),
+ grid_locator1=gl1,
+ tick_formatter1=tf1,
+ )
+
+ if fig is None:
+ fig = PLT.figure()
+
+ ax = FA.FloatingSubplot(fig, rect, grid_helper=ghelper)
+ fig.add_subplot(ax)
+
+ # Adjust axes
+ ax.axis["top"].set_axis_direction("bottom") # "Angle axis"
+ ax.axis["top"].toggle(ticklabels=True, label=True)
+ ax.axis["top"].major_ticklabels.set_axis_direction("top")
+ ax.axis["top"].label.set_axis_direction("top")
+ ax.axis["top"].label.set_text("Correlation")
+
+ ax.axis["left"].set_axis_direction("bottom") # "X axis"
+ ax.axis["left"].label.set_text("Standard deviation")
+
+ ax.axis["right"].set_axis_direction("top") # "Y axis"
+ ax.axis["right"].toggle(ticklabels=True)
+ ax.axis["right"].major_ticklabels.set_axis_direction("left")
+
+ ax.axis["bottom"].set_visible(False) # Useless
+
+ # Contours along standard deviations
+ ax.grid(False)
+
+ self._ax = ax # Graphical axes
+ self.ax = ax.get_aux_axes(tr) # Polar coordinates
+
+ # Add reference point and stddev contour
+ # print "Reference std:", self.refstd
+ l, = self.ax.plot([0], self.refstd, 'k*',
+ ls='', ms=10, label=label)
+ t = NP.linspace(0, NP.pi/2)
+ r = NP.zeros_like(t) + self.refstd
+ self.ax.plot(t,r, 'k--', label='_')
+
+ # Collect sample points for latter use (e.g. legend)
+ self.samplePoints = [l]
+
+ def add_sample(self, stddev, corrcoef, *args, **kwargs):
+ """Add sample (stddev,corrcoeff) to the Taylor diagram. args
+ and kwargs are directly propagated to the Figure.plot
+ command."""
+
+ l, = self.ax.plot(NP.arccos(corrcoef), stddev,
+ *args, **kwargs) # (theta,radius)
+ self.samplePoints.append(l)
+
+ return l
+
+ def add_rms_contours(self, levels=5, **kwargs):
+ """Add constant centered RMS difference contours."""
+
+ rs,ts = NP.meshgrid(NP.linspace(self.smin,self.smax),
+ NP.linspace(0,NP.pi/2))
+ # Compute centered RMS difference
+ rms = NP.sqrt(self.refstd**2 + rs**2 - 2*self.refstd*rs*NP.cos(ts))
+
+ contours = self.ax.contour(ts, rs, rms, levels, **kwargs)
+
+ def add_stddev_contours(self, std, corr1, corr2, **kwargs):
+ """Add a curved line with a radius of std between two points
+ [std, corr1] and [std, corr2]"""
+
+ t = NP.linspace(NP.arccos(corr1), NP.arccos(corr2))
+ r = NP.zeros_like(t) + std
+ return self.ax.plot(t,r,'red', linewidth=2)
+
+ def add_contours(self,std1,corr1,std2,corr2, **kwargs):
+ """Add a line between two points
+ [std1, corr1] and [std2, corr2]"""
+
+ t = NP.linspace(NP.arccos(corr1), NP.arccos(corr2))
+ r = NP.linspace(std1, std2)
+
+ return self.ax.plot(t,r,'red',linewidth=2)
+