Taylor Diagram Tutorial

This tutorial is for creating a Taylor Diagram using CDAT's VCS package.

Taylor diagrams are mathematical diagrams designed to graphically indicate which of several approximate representations (or models) of a system, process, or phenomenon is most realistic. This diagram, invented by Karl E. Taylor in 1994 (published in 2001), facilitates the comparative assessment of different models - for example, to summarize the relative merits of a collection of different models or to track changes in performance of a single model as it is modified. The diagram can also be used to quantify the degree of correspondence between modeled and observed behavior. In general, the diagram uses three statistics: the Pearson correlation coefficient, the root-mean-square error (RMSE), and the standard deviation. Taylor diagrams have been used widely to evaluate models designed to study climate and other aspects of Earth’s environment. (See Wikipedia's page and Taylor (2001) for details.)

Reference: Taylor, K. E. 2001: Summarizing multiple aspects of model performance in a single diagram. Journal of Geophysical Research, doi: 10.1029/2000JD900719, 106(D7): 7183-7192

Environment version used in this tutorial:

  • cdat 8.1

To download this Jupyter Notebook, right click on the link and choose "Download Linked File As..." or "Save Link as...". Remember where you saved the downloaded file which should have an .ipynb extension. (You'll need to launch the Jupyter notebook or JupyterLab instance from the location where you store the notebook file.)

Create VCS canvas

(Back to Top)

In [1]:
from __future__ import print_function

import vcs
x = vcs.init()

Prepare Input Data

(Back to Top)

Standard deviation and correlation values are required. The following creates hypothetical input named "data" for testing.

In [2]:
# Create 7 dummy data points representing 6 different models and 1 reference (observational) data point.
import MV2
corr = [.2, .5, .7, .85, .9, .95, .99]
std = [1.6, 1.7, 1.5, 1.2 , .8, .9, .98]

data_tmp1 = list(zip(std, corr))
data_tmp2 = list(data_tmp1)
In [3]:
data = MV2.array(data_tmp2)
data.id = "My Taylor Diagram Data"

print('data:\n', data)
print('data shape:', data.shape)
data:
 [[1.6  0.2 ]
 [1.7  0.5 ]
 [1.5  0.7 ]
 [1.2  0.85]
 [0.8  0.9 ]
 [0.9  0.95]
 [0.98 0.99]]
data shape: (7, 2)

Plot the initial version using VCS module. "vcs.createtaylordiagram" is for creating the template.

In [4]:
taylor = vcs.createtaylordiagram()
x.plot(data,taylor)
Out[4]:

Reference Line

(Back to Top)

The dotted curved line in the plot indicates a reference line. Let's say your reference data (i.e. your observations) has a standard deviation of 1.2. You may want to move the reference line to cross at 1.2, as shown below.

In [5]:
# Reference point
taylor.referencevalue=1.2
x.clear()
x.plot(data,taylor)
Out[5]:

Markers

(Back to Top)

You may want to distinguish the data points from each other and label them. You can adjust the marker as a shape and/or string, and create a legend.

In [6]:
# Marker attributes
ids = ["A1","A2","A3","B1","C1","C2","C3"]
id_sizes = [20., 15., 15., 15., 15., 15., 15.,]
id_colors = ["red","orange","green","cyan","blue","purple","black"]
symbols = ["square","dot","circle","triangle_right","triangle_left","triangle_up","triangle_down"]
colors = ["red","orange","green","cyan","blue","purple","black"]
sizes = [2., .5, 2., 2., 2., 2., 2.,]

For text strings:

  • ids: Data id text strings. It could be model or dataset names.
  • id_sizes: Sizes of text id strings.
  • id_colors: Colors of text id strings.

For symbols:

  • symbols: Shapes of markers.
  • colors: Colors of markers.
  • sizes: Sizes of markers symbols.

"id_colors" and "colors" are not required to be identical, but it is a good idea in most cases to use the same color for a given text string and its corresponding symbol.

In [7]:
taylor = vcs.createtaylordiagram()
taylor.referencevalue=1.2
for i in range(len(data)):
    taylor.addMarker(id=ids[i],
                     id_size=id_sizes[i],
                     id_color=id_colors[i],
                     symbol=symbols[i],
                     color=colors[i],
                     size=sizes[i])
x.clear()
x.plot(data,taylor)
Out[7]:

To adjust the position of text strings to avoid overlapping the symbol, use "xoffset" and "yoffset", which give the relative position from each of the (x, y) points. (The offsets can be positive or negative depending on where you want to position the text string labels.)

In [8]:
taylor = vcs.createtaylordiagram()
taylor.referencevalue=1.2
for i in range(len(data)):
    taylor.addMarker(id=ids[i],
                     id_size=id_sizes[i],
                     id_color=id_colors[i],
                     symbol=symbols[i],
                     color=colors[i],
                     size=sizes[i],
                     xoffset=-2.5,
                     yoffset=-5.5)
x.clear()
x.plot(data,taylor)
Out[8]:

An Alternative Way of Setting Makers

(Back to Top)

Instead of using a "for" loop and the "taylor.addMarker" function, you can store those pre-defined values in the Taylor diagram template directly.

For more information on templates, see the VCS Templates Tutorial.

In [9]:
# The other way to set marker attributes
taylor = vcs.createtaylordiagram()
taylor.Marker.id = ids
taylor.Marker.id_size = id_sizes
taylor.Marker.id_color = id_colors
taylor.Marker.symbol = symbols
taylor.Marker.color = colors
taylor.Marker.size = sizes
taylor.Marker.xoffset = [-2.5,]*len(data)
taylor.Marker.yoffset = [-5.5]*len(data)
taylor.referencevalue=1.2
x.clear()
x.plot(data,taylor)
Out[9]:

Create a Connecting Line Between Dots

(Back to Top)

If needed, you can draw connecting lines between individual data points. In the example below, the line connects all the data dots in the order they occur in the data.

In [10]:
taylor.Marker.line = ["tail","line","line","line","line","line","head"]
taylor.Marker.line_type = ["solid",]*len(data)
taylor.Marker.line_color = ["dark grey",]*len(data)
taylor.Marker.line_size = [5.,5.,5.,5.,5.,5.,5.]
x.clear()
x.plot(data,taylor)
Out[10]:

Grouping by Splitting Lines

(Back to Top)

Let's assume that you want to group your data. You can split a line in two by giving "None" for one of data points.

In [11]:
# Let's split the line into 2 sets of lines with an empty marker in between.
# The first line is dashed.
taylor.Marker.line =  ['tail', 'line', 'head', None, 'tail', 'line', 'head']
taylor.Marker.line_type = ["dash","dash","dash","solid","solid","solid","solid"]
x.clear()
x.plot(data,taylor)
Out[11]:

Legend

(Back to Top)

Instead of the legend at the bottom (the default position), you can move it where you want.

  • x1, x2, y1, y2 mark the four corners of the legend box and their values are a decimal fraction of the full page width (x) and length/height (y) which is 1.
In [12]:
# Legend positioning for quadrant 1
x.clear()
template = vcs.createtemplate(source="deftaylor")
template.legend.x1 = .5
template.legend.x2 = .6
template.legend.y1 = .2
template.legend.y2 = .65
template.legend.line = "black"
x.plot(data,taylor,template)
Out[12]:

Additional Axes

(Back to Top)

This first example uses the default skill function.

In [13]:
# Skill scores - using the default skill function
x.clear()
x.plot(data,taylor,skill=taylor.defaultSkillFunction)
Out[13]:

This second example uses a custom skill function.

In [14]:
# Skill scores - using a custom skill function
import numpy
def mySkill(s,r):
    return (4*numpy.ma.power(1+r,4))/(numpy.power(s+1./s,2)*numpy.power(1+r*2.,4))
x.clear()
x.plot(data,taylor,skill=mySkill)
Out[14]:

This third example uses the default skill function from the first example, but uses the template defined above to move the legend to the side.

In [15]:
# Skill scores - using the default skill function + the template to move the legend.
x.clear()
x.plot(data,taylor,template,skill=taylor.defaultSkillFunction)
Out[15]:

Two-Quadrants Taylor Diagram

(Back to Top)

In [16]:
# Negative correlation: Two quadrants
taylor.quadrans = 2 # default: 1

# Tweak input data to have negative number
data2 = data.copy()
data2[0,1] = -data2[0,1]

# Plot
x.clear()
x.plot(data2,taylor)
Out[16]:

Controllable Components

(Back to Top)

taylor.list() allows you to check all the components that you can control.

In [17]:
taylor = vcs.createtaylordiagram()
taylor.list()
---------- Taylordiagram (Gtd) member (attribute) listings ----------
graphic method = Gtd
name = __taylordiagram_983351763370163
detail = 75
max = None
quadrans = 1
skillValues = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95]
skillColor = (74.50980392156863, 74.50980392156863, 74.50980392156863, 100.0)
skillDrawLabels = y
skillCoefficient = [1.0, 1.0, 1.0]
idsLocation = 0
referencevalue = 1.0
arrowlength = 0.05
arrowangle = 20.0
arrowbase = 0.75
xticlabels1 = *
xmtics1 = *
yticlabels1 = *
ymtics1 = *
cticlabels1 = *
cmtics1 = *
Marker
    status =  []
    line =  []
    id =  []
    id_size =  []
    id_color =  []
    id_font =  []
    id_location =  []
    symbol =  []
    color =  []
    size =  []
    xoffset =  []
    yoffset =  []
    line_color =  []
    line_size =  []
    line_type =  []

Taylor Diagram


The CDAT software was developed by LLNL. This tutorial was written by Charles Doutriaux and Jiwoo Lee (18 Sep. 2017), with clarifying edits by Holly Davis (30 Sep. 2019). This work was performed under the auspices of the U.S. Department of Energy by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.

If you have questions about this notebook, please email our CDAT Support address, cdat-support@llnl.gov.