def plot_taylor_diag(std, corr, ref_std, normalized=True): import mpl_toolkits.axisartist.grid_finder as gf import mpl_toolkits.axisartist.floating_axes as fa # define polar axes transform tr = PolarAxes.PolarTransform() # define correlation labels rlocs = np.concatenate((np.arange(10) / 10., [0.95, 0.99])) tlocs = np.arccos(rlocs) gl1 = gf.FixedLocator(tlocs) tf1 = gf.DictFormatter(dict(zip(tlocs, map(str, rlocs)))) smin = 0 smax = max(2.0, 1.1 * std.max()) # add the curvilinear grid fig = plt.figure() ghelper = fa.GridHelperCurveLinear(tr, extremes=(0, np.pi / 2, smin, smax), grid_locator1=gl1, tick_formatter1=tf1) ax = fa.FloatingSubplot(fig, 111, grid_helper=ghelper) fig.add_subplot(ax) # adjust axes ax.axis["top"].set_axis_direction("bottom") 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") if normalize: ax.axis["left"].label.set_text("Normalized standard deviation") else: ax.axis["left"].label.set_text("Standard deviation") ax.axis["right"].set_axis_direction("top") ax.axis["right"].toggle(ticklabels=True) ax.axis["right"].major_ticklabels.set_axis_direction("left") ax.axis["bottom"].set_visible(False) ax.grid(True)
def __init__(self, fig=None, label='expected', max_normed_std=2.5, std_ratios=None, \ bias_vmin=None, bias_vmax=None, normalized=True, \ cmap=plt.cm.jet, s=80, title_expected=r'expected'): """ Set up Taylor diagram axes. """ self.normalized = normalized self.title_polar = r'Correlation' if self.normalized: self.title_xy = r'Normalized Standard Deviation' else: self.title_xy = r'Standard Deviation' self.max_normed_std = max_normed_std self.s_min = 0 self.std_ratios = std_ratios self.bias_vmin = bias_vmin self.bias_vmax = bias_vmax self.cmap = cmap self.s = s # marker size self.title_expected = title_expected # Correlation labels corln_r = np.concatenate((np.arange(10) / 10., [0.95, 0.99])) corln_ang = np.arccos(corln_r) # Conversion to polar angles grid_loc1 = gf.FixedLocator(corln_ang) # Positions tick_fmttr1 = gf.DictFormatter(dict(zip(corln_ang, map(str, corln_r)))) # Normalized standard deviation axis tr = PolarAxes.PolarTransform() grid_helper = fa.GridHelperCurveLinear( tr, extremes=( 0, np.pi / 2, # 1st quadrant self.s_min, self.max_normed_std), grid_locator1=grid_loc1, tick_formatter1=tick_fmttr1) self.fig = fig if self.fig is None: self.fig = plt.figure() # setup axes ax = fa.FloatingSubplot(self.fig, 111, grid_helper=grid_helper) # make the axis (polar ax child used for plotting) self.ax = self.fig.add_subplot(ax) # hide base-axis labels etc self.ax.axis['bottom'].set_visible(False) self._setup_axes() # attach the polar axes and plot the correlation lines self.polar_ax = self.ax.get_aux_axes(tr) self.polar_ax.plot([np.pi / 2.135, np.pi / 2.135], [self.s_min, self.max_normed_std], color='grey') self.polar_ax.plot([np.pi / 2.484, np.pi / 2.484], [self.s_min, self.max_normed_std], color='grey') self.polar_ax.plot([np.pi / 3, np.pi / 3], [self.s_min, self.max_normed_std], color='grey') self.polar_ax.plot([np.pi / 3.95, np.pi / 3.95], [self.s_min, self.max_normed_std], color='grey') self.polar_ax.plot([np.pi / 6.95, np.pi / 6.95], [self.s_min, self.max_normed_std], color='grey') # Add norm stddev ratio contours if self.normalized: self._plot_req_cont() self.points = []
def Taylor_diag(series, smax=1.5): """ Taylor Diagram : obs is reference data sample in a full diagram (0 --> npi) -------------------------------------------------------------------------- Input: series - dict with all time series (lists) to analyze series[0] - is the observation, the reference by default. """ corr,std ={},{} for i in series.keys(): corr[i] = ma.corrcoef(series[0],series[i])[1,0] std[i] = ma.std(series[i])/ma.std(series[0]) ref = 1# ma.std(series[0]) # radial grid # rlocs = np.concatenate((np.arange(0,1,0.2),[0.95,0.99])) # correlation coefficient tick marks rlocs = [0, .3, .6, .8, .95, .99] str_rlocs = np.concatenate((np.arange(0,1,0.2),[0.95,0.99],np.arange(0,10,0.2),[0.95,0.99])) tlocs = np.arccos(rlocs) # Conversion to polar angles gl1 = GF.FixedLocator(tlocs) # Positions tf1 = GF.DictFormatter(dict(zip(tlocs, map("{:.2f}".format, rlocs)))) # circumferencial grid str_locs2 = tlocs2 = np.arange(0, 2, 0.2) g22 = GF.FixedLocator(tlocs2) tf2 = GF.DictFormatter(dict(zip(tlocs2, map("{:.1f}".format, str_locs2)))) tr = PolarAxes.PolarTransform() smin = 0 ghelper = FA.GridHelperCurveLinear(tr, extremes=(0, np.pi/2, # 1st quadrant smin,smax), grid_locator1=gl1, tick_formatter1=tf1, tick_formatter2=tf2, ) fig = plt.figure(figsize=(7, 5), dpi=100) ax = FA.FloatingSubplot(fig, 111, grid_helper=ghelper) fig.add_subplot(ax) ax.axis["top"].set_axis_direction("bottom") 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 Coefficient") ax.axis["left"].set_axis_direction("bottom") ax.axis["left"].label.set_text("Standard Deviation") ax.axis["right"].set_axis_direction("top") ax.axis["right"].toggle(ticklabels=True, label=True) ax.axis["right"].set_visible(True) ax.axis["right"].major_ticklabels.set_axis_direction("bottom") #ax.axis["right"].label.set_text("Standard Deviation") ax.axis["bottom"].set_visible(False) ax.grid(True) ax = ax.get_aux_axes(tr) # radial RMS error lines from observed. t = np.linspace(0, np.pi) r = np.zeros_like(t) + ref ax.plot(t, r, 'k--', label='_') rs,ts = np.meshgrid(np.linspace(smin,smax), np.linspace(0,np.pi)) rms = np.sqrt(ref**2 + rs**2 - 2*ref*rs*np.cos(ts)) # CS = ax.contour(ts, rs, rms, colors='k', alpha=0.6, linewidths=1) # plt.clabel(CS, inline=1, fontsize=10) # plot observed point ax.plot(np.arccos(0.9999),ref,'k',marker='*',ls='', ms=10, label='Observed') # plot modelled points aux = [k for k in series.keys() if k != 0] for i in aux: ax.scatter(np.arccos(corr[i]), std[i], marker='o', label=i, zorder=5, s=50) # ax.text(np.arccos(corr[i]), std[i], i) plt.legend(bbox_to_anchor=(1.7, 1),prop=dict(size='large'),loc='best', fontsize=8) return fig, ax
def __init__(self, refstd, fig=None, rect=None, label='_', srange=(0, 1.5), extend=False): """ Set up Taylor diagram axes, i.e. single quadrant polar plot, using `mpl_toolkits.axisartist.floating_axes`. Parameters: * refstd: reference standard deviation to be compared to * fig: input Figure or None * rect: subplot definition * label: reference label * srange: stddev axis extension, in units of *refstd* * extend: extend diagram to negative correlations """ self.refstd = refstd # Reference standard deviation tr = PolarAxes.PolarTransform() # Correlation labels rlocs = numpy.array([0, 0.2, 0.4, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1]) if extend: # Diagram extended to negative correlations self.tmax = numpy.pi rlocs = numpy.concatenate((-rlocs[:0:-1], rlocs)) else: # Diagram limited to positive correlations self.tmax = numpy.pi / 2 tlocs = numpy.arccos(rlocs) # Conversion to polar angles gl1 = grid_finder.FixedLocator(tlocs) # Positions tf1 = grid_finder.DictFormatter(dict(zip(tlocs, map(str, rlocs)))) # set s locator gl2 = grid_finder.MaxNLocator(7) # Max 7 ticks # Standard deviation axis extent (in units of reference stddev) self.smin = srange[0] * self.refstd self.smax = srange[1] * self.refstd ghelper = floating_axes.GridHelperCurveLinear( tr, extremes=(0, self.tmax, self.smin, self.smax), grid_locator1=gl1, tick_formatter1=tf1, grid_locator2=gl2) self.fig = plt.figure() if fig is None else fig if rect is None: rect = 111 ax = floating_axes.FloatingSubplot(self.fig, rect, grid_helper=ghelper) self.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( "bottom" if extend else "left") if self.smin: ax.axis["bottom"].toggle(ticklabels=False, label=False) else: ax.axis["bottom"].set_visible(False) # Unused self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and stddev contour l, = self.ax.plot([0], self.refstd, 'k*', ls='', ms=10, label=label) t = numpy.linspace(0, self.tmax) r = numpy.zeros_like(t) + self.refstd self.ax.plot(t, r, 'k--', label='_', zorder=1) # Collect sample points for latter use (e.g. legend) self.sample_points = [l] # set color and marker styles self.ax.set_prop_cycle(get_point_style_cycler())
def TaylorDiagram(stddev,corrcoef,refstd,fig,colors,normalize=True): """Plot a Taylor diagram. This is adapted from the code by Yannick Copin found here: https://gist.github.com/ycopin/3342888 Parameters ---------- stddev : numpy.ndarray an array of standard deviations corrcoeff : numpy.ndarray an array of correlation coefficients refstd : float the reference standard deviation fig : matplotlib figure the matplotlib figure colors : array an array of colors for each element of the input arrays normalize : bool, optional disable to skip normalization of the standard deviation """ from matplotlib.projections import PolarAxes import mpl_toolkits.axisartist.floating_axes as FA import mpl_toolkits.axisartist.grid_finder as GF # define transform tr = PolarAxes.PolarTransform() # correlation labels rlocs = np.concatenate((np.arange(10)/10.,[0.95,0.99])) tlocs = np.arccos(rlocs) gl1 = GF.FixedLocator(tlocs) tf1 = GF.DictFormatter(dict(zip(tlocs,map(str,rlocs)))) # standard deviation axis extent if normalize: stddev = stddev/refstd refstd = 1. smin = 0 smax = max(2.0,1.1*stddev.max()) # add the curvilinear grid ghelper = FA.GridHelperCurveLinear(tr, extremes=(0,np.pi/2,smin,smax), grid_locator1=gl1, tick_formatter1=tf1) ax = FA.FloatingSubplot(fig, 111, grid_helper=ghelper) fig.add_subplot(ax) # adjust axes ax.axis["top"].set_axis_direction("bottom") 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") if normalize: ax.axis["left"].label.set_text("Normalized standard deviation") else: ax.axis["left"].label.set_text("Standard deviation") ax.axis["right"].set_axis_direction("top") ax.axis["right"].toggle(ticklabels=True) ax.axis["right"].major_ticklabels.set_axis_direction("left") ax.axis["bottom"].set_visible(False) ax.grid(True) ax = ax.get_aux_axes(tr) # Plot data corrcoef = corrcoef.clip(-1,1) for i in range(len(corrcoef)): ax.plot(np.arccos(corrcoef[i]),stddev[i],'o',color=colors[i],mew=0,ms=8) # Add reference point and stddev contour l, = ax.plot([0],refstd,'k*',ms=12,mew=0) t = np.linspace(0, np.pi/2) r = np.zeros_like(t) + refstd ax.plot(t,r, 'k--') # centralized rms contours rs,ts = np.meshgrid(np.linspace(smin,smax), np.linspace(0,np.pi/2)) rms = np.sqrt(refstd**2 + rs**2 - 2*refstd*rs*np.cos(ts)) contours = ax.contour(ts,rs,rms,5,colors='k',alpha=0.4) ax.clabel(contours,fmt='%1.1f') return ax
def __init__( self, ref_point: float, fig: Optional[plt.figure] = None, subplot: Optional[int] = 111, extend_angle: bool = False, corr_labels: Optional[np.ndarray] = None, ref_range: Tuple[float, float] = (0, 10), ref_label: str = "Reference Point", angle_label: str = "Correlation", var_label: str = "Standard Deviation", ) -> None: self.angle_label = angle_label self.ref_label = ref_label self.var_label = var_label self.extend_angle = extend_angle # correlation labels if corr_labels is None: corr_labels = np.array( [0, 0.2, 0.4, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1.0]) # extend if extend_angle: # Extend to negative correlations self.tmax = np.pi corr_labels = np.concatenate((-corr_labels[:0:-1], corr_labels)) else: # limit to only positive correlations self.tmax = np.pi / 2.0 # init figure if fig is None: fig = plt.figure(figsize=(8, 8)) # extend or not self.smin = ref_range[0] * ref_point self.smax = (ref_range[1] / 100) * ref_point + ref_point corr_ticks = np.arccos(corr_labels) gl1 = grid_finder.FixedLocator(corr_ticks) tf1 = grid_finder.DictFormatter( dict(zip(corr_ticks, map(str, corr_labels)))) # Grid Helper ghelper = floating_axes.GridHelperCurveLinear( aux_trans=PolarAxes.PolarTransform(), extremes=(0, self.tmax, self.smin, self.smax), grid_locator1=gl1, tick_formatter1=tf1, ) # create graphical axes ax = floating_axes.FloatingSubplot(fig, subplot, grid_helper=ghelper) fig.add_subplot(ax) self.graph_axes = ax self.polar_axes = ax.get_aux_axes(PolarAxes.PolarTransform()) self.sample_points = [] # Setup Axes self.reset_axes()
def __init__(self, refstd, fig=None, rect=111, label='_', srange=(0, 1.5), extend=False): """ Set up Taylor diagram axes, i.e. single quadrant polar plot, using `mpl_toolkits.axisartist.floating_axes`. Parameters: * refstd: reference standard deviation to be compared to * fig: input Figure or None * rect: subplot definition * label: reference label * srange: stddev axis extension, in units of *refstd* * extend: extend diagram to negative correlations """ 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.array([0, 0.2, 0.4, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1]) if extend: # Diagram extended to negative correlations self.tmax = NP.pi rlocs = NP.concatenate((-rlocs[:0:-1], rlocs)) else: # Diagram limited to positive correlations self.tmax = NP.pi / 2 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 (in units of reference stddev) self.smin = srange[0] * self.refstd self.smax = srange[1] * self.refstd ghelper = FA.GridHelperCurveLinear(tr, extremes=(0, self.tmax, 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"].major_ticklabels.set_fontsize(15) ax.axis["top"].label.set_axis_direction("top") ax.axis["top"].label.set_text("Standardized gauge density") ax.axis["top"].label.set_fontsize(15) ax.axis["left"].set_axis_direction("bottom") # "X axis" ax.axis["left"].label.set_text("RMSD (mm/h)") ax.axis["left"].label.set_fontsize(15) ax.axis["left"].major_ticklabels.set_fontsize(15) ax.axis["right"].set_axis_direction("top") # "Y-axis" ax.axis["right"].toggle(ticklabels=True) ax.axis["right"].major_ticklabels.set_axis_direction( "bottom" if extend else "left") ax.axis["right"].major_ticklabels.set_fontsize(15) ax.axis["right"].label.set_text("RMSD (mm/h)") ax.axis["right"].label.set_fontsize(15) if self.smin: ax.axis["bottom"].toggle(ticklabels=False, label=False) else: ax.axis["bottom"].set_visible(False) # Unused self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and stddev contour l, = self.ax.plot([0], self.refstd, '.', ls='', ms=10, label=label) t = NP.linspace(0, self.tmax) 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 __init__(self, refstd, 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 gl2_num = np.linspace(0, 1.5, 7) gl2 = GF.FixedLocator(gl2_num) gl2_ticks = [(x, str(x)) for x in gl2_num] gl2_ticks[-1] = [gl2_num[-1], ''] gl2_ticks[0] = [gl2_num[0], '0'] tf1 = GF.DictFormatter(dict(list(zip(tlocs, list(map(str, rlocs)))))) tf2 = GF.DictFormatter(dict(gl2_ticks)) # Standard deviation axis extent self.smin = min(gl2_num) #self.smax = 1.5*self.refstd self.smax = max(gl2_num) ghelper = FA.GridHelperCurveLinear( tr, extremes=( 0, np.pi / 2, # 1st quadrant self.smin, self.smax), grid_locator1=gl1, grid_locator2=gl2, tick_formatter1=tf1, tick_formatter2=tf2) # 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 (Normalized)") 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) # Shrink current axis by 20% box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.8, box.height * 0.8]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) 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 setup_axes(self): """Set up Taylor diagram axes, i.e. single quadrant polar plot, using mpl_toolkits.axisartist.floating_axes. """ tr = PolarTransform() # Intervals on the axis of the correlation coefficient rlocs = np.concatenate(([-1.0, -0.99, -0.95], np.arange(-10, 0) / 10.0, np.arange(10) / 10.0, [0.95, 0.99])) # The same intervals as angles tlocs = np.arccos(rlocs) # Conversion to polar angles gl1 = GF.FixedLocator(tlocs) # Positions tf1 = GF.DictFormatter( dict(zip(tlocs, map(str, rlocs))) ) # maps coefficient angles to string representation of correlation coefficient x_max = np.pi if self.show_negative_corrcoeff else np.pi / 2 x_axis_range = (0, x_max) y_axis_range = (0, self.max_stddev) ghelper = FA.GridHelperCurveLinear( tr, extremes=(x_axis_range[0], x_axis_range[1], y_axis_range[0], y_axis_range[1]), grid_locator1=gl1, tick_formatter1=tf1, ) ax = FA.FloatingSubplot( self.fig, 111, grid_helper=ghelper ) # 111 -> plot contains 1 row, 1 col and shall be located at position 1 (1-based!) in the resulting grid self.fig.add_subplot(ax) if self.show_negative_corrcoeff: self.fig.text(0.41, 0.178, 'Standard Deviation' ) # magic numbers: place label central below plot # Setup 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 coefficient") if not self.show_negative_corrcoeff: ax.axis["left"].set_axis_direction("bottom") # "X axis" ax.axis["left"].label.set_text("Standard deviation") else: ax.axis["left"].set_axis_direction("bottom") # "X axis" ax.axis["right"].set_axis_direction("top") # "Y axis" ax.axis["right"].toggle(ticklabels=True, label=True) tick_axis_direction = "bottom" if self.show_negative_corrcoeff else "left" ax.axis["right"].major_ticklabels.set_axis_direction( tick_axis_direction) label_axis_direction = "bottom" if self.show_negative_corrcoeff else "left" ax.axis["right"].label.set_axis_direction(label_axis_direction) if not self.show_negative_corrcoeff: ax.axis["right"].label.set_text("Standard deviation") ax.axis["bottom"].set_visible(False) # Hide useless axis # Grid ax.grid() # This defines how to draw the data -- putting the polar transform here forces the plot to draw the data on # the polar plot instead of a rectangular one self.ax = ax.get_aux_axes(tr) # Add reference points # [0] = x-value # stddev = y-value for name, ref_stddev, unit in self.ref: dataset = self.ax.plot([0], ref_stddev, '%so' % self.get_color())[0] if hasattr(self, 'sample_names'): self.sample_points.append(dataset) self.sample_names.append( create_sample_name(name, unit, self.use_absolute_stddev)) else: self.sample_points = [dataset] self.sample_names = [ create_sample_name(name, unit, self.use_absolute_stddev) ] # Add stddev contours t = np.linspace(0, x_max, num=50) for name, ref_stddev, unit in self.ref: if not np.isnan(ref_stddev): r = np.zeros_like(t) + ref_stddev # 50 times the stddev self.ax.plot(t, r, 'k--', label='_', linewidth=0.5) # Add rmse contours rs, ts = np.meshgrid(np.linspace(0, y_axis_range[1], num=50), np.linspace(0, x_max, num=50)) for name, ref_stddev, unit in self.ref: if not np.isnan(ref_stddev): # Unfortunately, I don't understand the next line AT ALL, # it's copied from http://matplotlib.1069221.n5.nabble.com/Taylor-diagram-2nd-take-td28070.html # but it leads to the right results (contours of the centered pattern RMS), so I keep it rmse = np.sqrt(ref_stddev**2 + rs**2 - 2 * ref_stddev * rs * np.cos(ts)) colors = ('#7F0000', '#6F0000', '#5F0000', '#4F0000', '#3F0000', '#2F0000', '#1F0000', '#0F0000') rmse_contour = self.ax.contour(ts, rs, rmse, 8, linewidths=0.5, colors=colors) plt.clabel(rmse_contour, inline=1, fmt='%1.2f', fontsize=8)
def taylor_ax(fig, *args, **kw): #th1=0., th2=np.pi/3, rd1=0., rd2=1.2, tloc1=None, tloc2=None) tr = PolarAxes.PolarTransform() # Correlation labels if kw.has_key("tloc1"): rlocs = kw["tloc1"] else: rlocs = np.concatenate((np.arange(10) / 10., [0.95, 0.99])) tlocs = np.arccos(rlocs) gl1 = GF.FixedLocator(tlocs) tf1 = GF.DictFormatter(dict(zip(tlocs, map(str, rlocs)))) if kw.has_key("tloc2"): gl2 = GF.FixedLocator(kw["tloc2"]) else: gl2 = GF.MaxNLocator(10) if kw.has_key("th1"): th1 = kw["th1"] else: th1 = 0. if kw.has_key("th2"): th2 = kw["th2"] else: th2 = np.pi / 2 if kw.has_key("rd1"): rd1 = kw["rd1"] else: rd1 = 0. if kw.has_key("rd2"): rd2 = kw["rd2"] else: rd2 = 1.65 ghelper = FA.GridHelperCurveLinear( tr, extremes=(th1, th2, rd1, rd2), grid_locator1=gl1, grid_locator2=gl2, tick_formatter1=tf1, tick_formatter2=None, ) ax = FA.FloatingSubplot(fig, *args, grid_helper=ghelper) fig.add_subplot(ax) # Adjust axes fontsize = 9 ax.axis["top"].set_axis_direction("bottom") # "Angle axis" ax.axis["top"].toggle(ticklabels=True, label=True) ax.axis["top"].major_ticklabels.set_size('xx-small') 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["top"].label.set_fontsize(fontsize) ax.axis["left"].set_axis_direction("right") # "X axis" ticks_font = 2 ax.axis["left"].major_ticklabels.set_size('xx-small') ax.axis["left"].major_ticks.set_ticksize(ticks_font) # "X axis" ax.axis["left"].label.set_text("Normalized standard deviation") ax.axis["left"].label.set_fontsize(fontsize) ax.axis["right"].major_ticklabels.set_size('xx-small') ax.axis["right"].set_axis_direction("top") # "Y axis" ax.axis["right"].toggle(ticklabels=True) ax.axis["right"].major_ticks.set_ticksize(ticks_font) # "Y axis" ax.axis["right"].major_ticklabels.set_axis_direction("left") ax.axis["right"].label.set_fontsize(fontsize) ax.axis["bottom"].set_visible(False) # turn off overlaying tickmark ax.grid(linewidth=0.5, color='gray') aux_ax = ax.get_aux_axes(tr) # Polar coordinates aux_ax.th1 = th1 aux_ax.th2 = th2 aux_ax.rd1 = rd1 aux_ax.rd2 = rd2 ax.th1 = th1 ax.th2 = th2 ax.rd1 = rd1 ax.rd2 = rd2 return ax, aux_ax
def __init__(self, refstd, 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 from mpl_toolkits.axisartist import floating_axes from mpl_toolkits.axisartist import grid_finder 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 = grid_finder.FixedLocator(tlocs) # Positions. dict_formatter = dict(list(zip(tlocs, map(str, rlocs)))) tf1 = grid_finder.DictFormatter(dict_formatter) # Standard deviation axis extent. self.smin = 0 self.smax = 1.5 * self.refstd extremes = ( 0, np.pi / 2, # 1st quadrant. self.smin, self.smax) ghelper = floating_axes.GridHelperCurveLinear(tr, extremes=extremes, grid_locator1=gl1, tick_formatter1=tf1) if fig is None: fig = plt.figure() ax = floating_axes.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. l, = self.ax.plot([0], self.refstd, 'ko', 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 setup_axes(self, fig, rect=111, extra_graph=1.5, quadrant=1, print_bool=False, *args, **kwargs): """Set up Taylor diagram axes, i.e. single quadrant polar plot, using mpl_toolkits.axisartist.floating_axes. Wouldn't the ideal be to define its own non-linear transformation, so that coordinates are directly r=stddev and theta=correlation? I guess it would allow """ self.extra_graph = extra_graph tr = PolarAxes.PolarTransform() # Correlation labels if quadrant == 1: rlocs = np.concatenate((np.arange(0, 10, 1) / 10., [0.95, 0.99])) extremes = (0, np.pi / 2, 0, extra_graph * self.ref_STD) elif quadrant == 2: rlocs = np.concatenate( ([-0.99, -0.95], np.arange(-9, 10, 1) / 10., [0.95, 0.99])) extremes = (0, np.pi, 0, extra_graph * self.ref_STD) else: raise ValueError("'quadrant' should be 1 or 2.") tlocs = np.arccos(rlocs) # Conversion to polar angles gl1 = GF.FixedLocator(tlocs) # Positions tf1 = GF.DictFormatter(dict(zip(tlocs, map(str, rlocs)))) ghelper = FA.GridHelperCurveLinear( tr, extremes=extremes, grid_locator1=gl1, tick_formatter1=tf1, ) 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["right"].label.set_text("Standard deviation") ax.axis["right"].label._visible = True ax.axis["bottom"].set_visible(False) # Useless # Grid ax.grid() self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and stddev contour if print_bool: print "Reference std:", self.ref_STD self.ax.plot([0], self.ref_STD, 'bo', label=self.ref_label, markersize=2. * markersize) self.ax.text(-0.045, self.ref_STD, "\\textbf{%s}" % self.ref_label, color='b', fontsize=fontsize, horizontalalignment='left', verticalalignment='top') if quadrant == 1: t = np.linspace(0., np.pi / 2) elif quadrant == 2: t = np.linspace(0., np.pi) else: raise ValueError("'quadrant' should be 1 or 2.") r = np.zeros_like(t) + self.ref_STD self.ax.plot(t, r, 'k--') return ax
def __init__(self, datastd, fig=None, rect=111, normalize='Y', sd_axis_frac=1.5, fontsize=10): #Impot the things we need from matplotlib.projections import PolarAxes import mpl_toolkits.axisartist.floating_axes as fa import mpl_toolkits.axisartist.grid_finder as gf # Check if we are going to be normalizing values or not, and set # values appropriately. if normalize == 'Y': self.datastd = datastd / datastd self.normfactor = datastd else: self.datastd = datastd self.normfactor = 1 # Standard deviation axis extent self.smin = 0 self.smax = sd_axis_frac * self.datastd 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)))) # Std. Dev. labels sdlocs = np.linspace(self.smin, self.smax, 7) # Round the output (particularly import when normalize='N') sdlocs = [ round(sd, -int(np.floor(np.log10(sd))) + 2) for sd in sdlocs[1:] ] sdlocs.append(0) gl2 = gf.FixedLocator(sdlocs) tf2 = gf.DictFormatter(dict(zip(sdlocs, map(str, sdlocs)))) ghelper = fa.GridHelperCurveLinear( tr, extremes=( 0, np.pi / 2, # 1st quadrant self.smin, self.smax), grid_locator1=gl1, grid_locator2=gl2, tick_formatter1=tf1, tick_formatter2=tf2) # Check if an existing figure has been passed to the program 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") # Azimuthal 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"].major_ticklabels.set_color("darkgreen") ax.axis["top"].label.set_color("darkgreen") ax.axis["top"].label.set_text("Correlation") ax.axis["top"].label.set_fontsize(fontsize) ax.axis["left"].set_axis_direction("bottom") # X axis ax.axis["left"].toggle(ticklabels=True) ax.axis["right"].set_axis_direction("top") # Y axis ax.axis["right"].toggle(ticklabels=True, label=True) ax.axis["right"].major_ticklabels.set_axis_direction("left") if normalize == 'Y': ax.axis["right"].label.set_text("Normalised standard deviation") else: ax.axis["right"].label.set_text("Standard deviation") ax.axis["right"].label.set_fontsize(fontsize) ax.axis["bottom"].set_visible(False) # Don't want it # Contours for each standard deviation ax.grid(False) self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and ref stddev contour l, = self.ax.plot([0], self.datastd, 'k*', ls='', ms=10) t = np.linspace(0, np.pi / 2) r = np.zeros_like(t) + self.datastd self.ax.plot(t, r, 'k--', label='_', alpha=0.75) # Collect data points for latter use (e.g. legend) self.samplePoints = [l] #Add "correlation lines" for i in np.concatenate((np.arange(1, 10) / 10., [0.99])): self.ax.plot([np.arccos(i), np.arccos(i)], [0, self.smax], c='darkgreen', alpha=0.35)
def __init__(self, refstd, fig=None, rect=111, label=None, cors=[0.3, 0.6, 0.9]): """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 as axisartist 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., 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.0 self.smax = 1.6 * self.refstd gl2 = GF.MaxNLocator(10) #[0, 0.2,0.4,0.6, 0.8,1.0,1.2,1.4] ghelper = FA.GridHelperCurveLinear( tr, extremes=( 0, NP.pi / 2.0, # 1st quadrant self.smin, self.smax), grid_locator1=gl1, grid_locator2=gl2, tick_formatter1=tf1, tick_formatter2=None, ) ghelper.grid_finder.grid_locator2._nbins = 4 if fig is None: fig = PLT.figure() ax = FA.FloatingSubplot(fig, rect, grid_helper=ghelper) fig.add_subplot(ax) # Adjust axes PLT.setp(ax.spines.values(), visible=False) 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["top"].label.set_fontsize(9) ax.axis[:].major_ticklabels.set_fontsize(12) ax.axis["left"].set_axis_direction("right") # "X axis" ax.axis["left"].toggle(ticklabels=True, label=True) ax.axis["left"].toggle(ticklabels=False, label=False) ax.axis["left"].label.set_text("Normalized std.") ax.axis["left"].label.set_fontsize(9) ax.axis["right"].set_axis_direction("top") # "Y axis" ax.axis["right"].toggle(ticklabels=True, label=True) ax.axis["right"].major_ticklabels.set_axis_direction("left") ax.axis["right"].label.set_fontsize(9) 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 l, = self.ax.plot([0], self.refstd, color='black', marker='o', ls='', ms=10, label="OBS") t = NP.linspace(0, NP.pi / 2.0) r = NP.zeros_like(t) + self.refstd lines = self.ax.plot(t, r, color='darkgray', ls='--', label='_', zorder=0, lw=0.8) for isec in cors: rad = NP.arccos(isec) stds = NP.linspace(self.smin, self.smax) rad0 = [rad for x in stds] lines = self.ax.plot(rad0, stds, color='darkgray', ls='--', zorder=0, lw=0.8) self.samplePoints = [l]
def Taylor_diag(series, names): """ Taylor Diagram : obs is reference data sample in a full diagram (0 --> npi) -------------------------------------------------------------------------- Input: series - dict with all time series (lists) to analyze series[0] - is the observation, the reference by default. """ corr, std = {}, {} for i in series.keys(): corr[i] = ma.corrcoef(series[0], series[i])[1, 0] std[i] = ma.std(series[i]) / ma.std(series[0]) ref = 1 # ma.std(series[0]) #print corr rlocs = np.concatenate((np.arange(0, -10, -0.25), [-0.95, -0.99], np.arange(0, 10, 0.25), [0.95, 0.99])) str_rlocs = np.concatenate( (np.arange(0, 10, 0.25), [0.95, 0.99], np.arange(0, 10, 0.25), [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)))) str_locs2 = np.arange(-10, 11, 0.5) tlocs2 = np.arange(-10, 11, 0.5) # Conversion to polar angles g22 = GF.FixedLocator(tlocs2) tf2 = GF.DictFormatter(dict(zip(tlocs2, map(str, str_locs2)))) tr = PolarAxes.PolarTransform() smin = 0 smax = 2.5 ghelper = FA.GridHelperCurveLinear( tr, extremes=( 0, np.pi, # 1st quadrant smin, smax), grid_locator1=gl1, #grid_locator2=g11, tick_formatter1=tf1, tick_formatter2=tf2, ) fig = plt.figure(figsize=(10, 5), dpi=100) ax = FA.FloatingSubplot(fig, 111, grid_helper=ghelper) fig.add_subplot(ax) ax.axis["top"].set_axis_direction("bottom") 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 Coefficient") ax.axis["left"].set_axis_direction("bottom") ax.axis["left"].label.set_text("Standard Deviation") ax.axis["right"].set_axis_direction("top") ax.axis["right"].toggle(ticklabels=True, label=True) ax.axis["right"].set_visible(True) ax.axis["right"].major_ticklabels.set_axis_direction("bottom") #ax.axis["right"].label.set_text("Standard Deviation") ax.axis["bottom"].set_visible(False) ax.grid(True) ax = ax.get_aux_axes(tr) t = np.linspace(0, np.pi) r = np.zeros_like(t) + ref ax.plot(t, r, 'k--', label='_') rs, ts = np.meshgrid(np.linspace(smin, smax), np.linspace(0, np.pi)) rms = np.sqrt(ref**2 + rs**2 - 2 * ref * rs * np.cos(ts)) CS = ax.contour(ts, rs, rms, cmap=cm.bone) plt.clabel(CS, inline=1, fontsize=10) ax.plot(np.arccos(0.9999), ref, 'k', marker='*', ls='', ms=10) aux = range(1, len(corr)) #del aux[ref] colors = plt.matplotlib.cm.jet(np.linspace(0, 1, len(corr))) for i in aux: ax.plot(np.arccos(corr[i]), std[i], c=colors[i], alpha=0.7, ms=15, marker='o', label="%s" % names[i]) ax.text(np.arccos(corr[i]), std[i], "%s" % i) legend(bbox_to_anchor=(1.5, 1), prop=dict(size='large'), loc='best') plt.savefig('example.png', dpi=300) return
def taylorDiagram(benchmarks, savepath='', fname='', debug=False): """ References: Taylor, K.E.: Summarizing multiple aspects of model performance in a single diagram. J. Geophys. Res., 106, 7183-7192, 2001 (also see PCMDI Report 55, http://www-pcmdi.llnl.gov/publications/ab55.html) IPCC, 2001: Climate Change 2001: The Scientific Basis, Contribution of Working Group I to the Third Assessment Report of the Intergovernmental Panel on Climate Change Houghton, J.T., Y. Ding, D.J. Griggs, M. Noguer, P.J. van der Linden, X. Dai, K. Maskell, and C.A. Johnson (eds.) Cambridge University Press, Cambridge, United Kingdom and New York, NY, USA, 881 pp. (see http://www.grida.no/climate/ipcc_tar/wg1/317.htm#fig84) Code inspired by Yannick Copin's code (see https://github.com/ycopin) """ if debug: print "Plotting time-series..." # Setting up graph 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 smin = 0 smax = 1.5 ghelper = fa.GridHelperCurveLinear(tr, extremes=(0, np.pi / 2, smin, smax), grid_locator1=gl1, tick_formatter1=tf1) fig = plt.figure(figsize=(18, 10)) rect = 111 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) _ax = ax # Graphical axes ax = ax.get_aux_axes(tr) # Polar coordinates # Reference lines x95 = [0.05, 13.9] # For Prcp, this is for 95th level (r = 0.195) y95 = [0.0, 71.0] x99 = [0.05, 19.0] # For Prcp, this is for 99th level (r = 0.254) y99 = [0.0, 70.0] ax.plot(x95, y95, color='k') ax.plot(x99, y99, color='k') # Add reference point and stddev contour l, = ax.plot(0.0, 1.0, 'k*', ls='', ms=10, label='Reference') t = np.linspace(0, np.pi / 2) r = np.zeros_like(t) + 1.0 ax.plot(t, r, 'k--', label='_') samplePoints = [l] # Plot points sampleLenght = benchmarks['Type'].shape[0] colors = plt.matplotlib.cm.jet(np.linspace(0, 1, sampleLenght)) for i in range(sampleLenght): l, = ax.plot(benchmarks['NRMSE'][i] / 100.0, benchmarks['r2'][i], marker='$%d$' % (i + 1), ms=10, ls='', mfc=colors[i], mec=colors[i], label=benchmarks['Type'][i] + " " + benchmarks['gear'][i]) samplePoints.append(l) t = np.linspace(0, np.pi / 2) r = np.zeros_like(t) + 1.0 ax.plot(t, r, 'k--', label='_') # Add NRMS contours, and label them rs, ts = np.meshgrid(np.linspace(smin, smax), np.linspace(0, np.pi / 2)) # Compute centered RMS difference rms = np.sqrt(1.0 + rs**2 - 2 * rs * np.cos(ts)) contours = ax.contour(ts, rs, rms, 5, colors='0.5') ax.clabel(contours, inline=1, fontsize=10, fmt='%.1f') # Add a figure legend fig.legend(samplePoints, [p.get_label() for p in samplePoints], numpoints=1, prop=dict(size='small'), loc='upper right') fig.tight_layout() if savepath.strip() and fname.strip(): if os.exists(savepath): fig.savefig(savepath + fname) plt.close(fig) else: fig.show() plt.show()
def generateGrid(self, fig=None, srange=(0,1.5), rect=111): from matplotlib.projections import PolarAxes import mpl_toolkits.axisartist.floating_axes as FA import mpl_toolkits.axisartist.grid_finder as GF tr = PolarAxes.PolarTransform() # Correlation labels rlocs = NP.concatenate((NP.arange(10)/10.,[0.95,0.99],-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 (in units of reference stddev) self.smin = srange[0]*self.refStd self.smax = srange[1]*self.refStd steps = NP.round((self.smax - self.smin) / 10,1) xticks = NP.arange(self.smin, self.smax, steps) tf2 = GF.DictFormatter(dict(zip(xticks, map(str, xticks)))) gl2= GF.FixedLocator(xticks) ghelper = FA.GridHelperCurveLinear(tr, extremes=(0, self.width, self.smin, self.smax), grid_locator1=gl1, tick_formatter1=tf1, tick_formatter2=tf2, grid_locator2=gl2) if fig is None: fig = plt.figure(figsize=(10, 10)) self.figure = fig 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["left"].label.set_ha(self.labelPosition) ax.axis["right"].set_axis_direction("top") # "Y axis" ax.axis["right"].toggle(ticklabels=True) ax.axis["right"].major_ticklabels.set_axis_direction(self.labelDirection) ax.axis["bottom"].set_visible(False) # Useless self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates self._add_contours(colors = '0.5') plt.title("Taylor diagram") # Figure title return fig
def taylorDiagram(predicted, observed, norm=False, addTo=None, modelName='', isoSTD=True): """Taylor diagrams for comparing model performance Parameters ========== predicted : array-like predicted data observed : array-like observation vector Other Parameters ================ norm : boolean or float Selects whether the values should be normalized (default is False). If a value is given this will be used to normalize the inputs. xyline : boolean Toggles the display of a line of y=x (perfect model). Default True. addTo : axes, or None The object on which plotting will happen. If **None** (default) then a figure and axes will be created. If matplotlib axes are given then the plot will be made on those axes, assuming that the point is being added to a previously generated Taylor diagram. modelName : string Name of model to label the point on the Taylor diagram with. isoSTD : boolean Toggle for isocontours of standard deviation. Default is True, but turning them off can reduce visual clutter or prevent intereference with custom plot styles that alter background grid behavior. Returns ======= out_dict : dict A dictionary containing the Figure, the Axes, and 'Norm' (the value used to normalize the inputs/outputs). Example ======= >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from verify.plot import taylorDiagram >>> model1 = np.random.randint(0,40,101).astype(float) >>> model2 = model1*(1 + np.arange(101)/70) >>> obs = model1 + np.random.randn(101) >>> obs[[2,3,8,9,15,16,30,31]] = obs[[31,30,16,15,9,8,3,2]] >>> obs *= 0.25 + (5-(np.arange(101)/30.))/4 >>> result1 = taylorDiagram(model1, obs, norm=True, modelName='A') >>> result2 = taylorDiagram(model2, obs, norm=result1['Norm'], >>> modelName='B', addTo=result1['Axes']) >>> plt.show() Notes ===== Based on ''Summarizing multiple aspects of model performance in a single diagram' by K.E. Taylor (Radio Science, 2001; doi: 10.1029/2000JD900719) and 'Taylor Diagram Primer' by Taylor (document at https://pcmdi.llnl.gov/staff/taylor/CV/Taylor_diagram_primer.pdf) With some implementation aspects inspired by the public domain code of github user ycopin at https://gist.github.com/ycopin/3342888 """ #fancy plotting imports from mpl_toolkits.axisartist import floating_axes, angle_helper, grid_finder from matplotlib.projections import PolarAxes pred = _maskSeries(predicted) obse = _maskSeries(observed) pstd = pred.std(ddof=1) #unbiased sample std.dev. model ostd = obse.std(ddof=1) #unbiased sample std.dev. observed pcorr = numpy.corrcoef(obse, pred)[0, 1] # Pearson's r pbias = bias(pred, obse) #mean error # Normalize on request if norm: setNormed = True normfac = ostd ostd = ostd / normfac pstd = pstd / normfac else: setNormed = False normfac = 1 tr = PolarAxes.PolarTransform() # Correlation labels corrtickvals = numpy.asarray(list(range(10)) + [9.5, 9.9]) / 10. corrtickvals_polar = numpy.arccos(corrtickvals) # Round labels to nearest N digits corrticklabs = [] for cval in corrtickvals: lab = '{0:0.2f}'.format(cval) if str(cval)[2] != '0' else \ '{0:0.1f}'.format(cval) corrticklabs.append('{0:0.2f}'.format(cval)) valsAndLabs = list(zip(corrtickvals_polar, corrticklabs)) corrgrid = grid_finder.FixedLocator(corrtickvals_polar) corrticks = grid_finder.DictFormatter(dict(valsAndLabs)) # Std. Dev. tick values and labels smin, smax = 0, numpy.ceil(0.8335 * ostd) * 2 stdtickvals = numpy.linspace(smin, smax, 9) # Round labels to nearest N digits stdticklabs = [] for stdval in stdtickvals: stdticklabs.append('{0:0.2f}'.format(stdval)) valsAndLabs = list(zip(stdtickvals, stdticklabs)) stdgrid = grid_finder.FixedLocator(stdtickvals) stdticks = grid_finder.DictFormatter(dict(valsAndLabs)) gh_curvegrid = floating_axes.GridHelperCurveLinear( tr, extremes=(0, numpy.pi / 2, smin, smax), grid_locator1=corrgrid, grid_locator2=stdgrid, tick_formatter1=corrticks, tick_formatter2=stdticks) artists = [] #if addTo isn't None then assume we've been given a previously returned #axes object if addTo is None: fig = plt.figure() ax = floating_axes.FloatingSubplot(fig, '111', grid_helper=gh_curvegrid) fig.add_subplot(ax) #Adjust axes following matplotlib gallery example #Correlation is angular coord ax.axis['top'].set_axis_direction('bottom') ax.axis['top'].toggle(ticklabels=True, label=True) ax.axis['top'].major_ticklabels.set_axis_direction('top') ax.axis['top'].major_ticklabels.set_color('royalblue') ax.axis['top'].label.set_axis_direction('top') ax.axis['top'].label.set_color('royalblue') ax.axis['top'].label.set_text("Pearson's r") #X-axis ax.axis['left'].set_axis_direction('bottom') ax.axis['left'].toggle(ticklabels=True) #Y-axis ax.axis['right'].set_axis_direction('top') ax.axis['right'].toggle(ticklabels=True, label=True) ax.axis['right'].major_ticklabels.set_axis_direction('left') if setNormed: xylabel = 'Normalized standard deviation' else: xylabel = 'Standard deviation' ax.axis['right'].label.set_text(xylabel) ax.axis['left'].label.set_text(xylabel) ax.axis['bottom'].set_visible(False) _ax = ax # Display axes #Figure set up, done we work with the transformed axes ax = ax.get_aux_axes(tr) # Axes referenced in polar coords #Add reference point, ref stddev contour and other stddev contours artists.append( ax.scatter(0, ostd, marker='o', linewidths=2, edgecolors='black', facecolors='None', label='Observation', zorder=99)) azim = numpy.linspace(0, numpy.pi / 2) rad = numpy.zeros_like(azim) rad.fill(ostd) ax.plot(azim, rad, 'k--', alpha=0.75) if isoSTD: for sd in stdtickvals[::2]: rad.fill(sd) ax.plot(azim, rad, linestyle=':', color='dimgrey', alpha=0.75, zorder=3) #Add radial markers at correlation ticks for i in corrtickvals[1:]: ax.plot([numpy.arccos(i), numpy.arccos(i)], [0, smax], c='royalblue', alpha=0.5, zorder=40) #Add contours of centered RMS error rs, ts = numpy.meshgrid(numpy.linspace(smin, smax), numpy.linspace(0, numpy.pi / 2)) rms = numpy.sqrt(ostd**2 + rs**2 - 2 * ostd * rs * numpy.cos(ts)) contours = ax.contour(ts, rs, rms, 4, alpha=0.75, zorder=30, colors='dimgray') plt.clabel(contours, inline=True, fontsize='smaller', fmt='%1.2f') else: #TODO: add some testing/error handling here ax = addTo fig = ax.figure #add present model stdextent = smax - smin twopercent = stdextent / 50.0 artists.append( ax.scatter(numpy.arccos(pcorr), pstd, marker='o', label=modelName, zorder=99)) dum = ax.text(numpy.arccos(pcorr), pstd + twopercent, modelName, fontsize='larger') out = dict() out['Figure'] = fig out['Axes'] = ax out['Norm'] = normfac out['Artists'] = artists return out
def __init__(self, refstd=1, fig=None, rect=111, label='REF', std_range=(0, 1.65), std_level=np.arange(0, 1.51, 0.25)): """Create base Taylor Diagram. Parameters ---------- refstd : float, optional reference standard deviation fig : matplotlib.figure.Figure, optional Optional input figure. Default is None rect : int, optional Optional subplot definition label : string, optional Optional reference label string indentifier std_range : Tuple, optional Optional stddev axis extent std_level : list, optional Optional list of tick locations for stddev axis """ from matplotlib.projections import PolarAxes import mpl_toolkits.axisartist.floating_axes as fa import mpl_toolkits.axisartist.grid_finder as gf # Pull and set optional constructor variables # Set figure self.fig = fig if fig is None: self.fig = plt.figure(figsize=(8, 8)) # Reference standard deviation self.refstd = refstd # Standard deviation axis extent (in units of reference stddev) self.smin = std_range[0] self.smax = std_range[1] # Set polar transform tr = PolarAxes.PolarTransform() # Set correlation labels rlocs = np.concatenate((np.arange(10) / 10., [0.95, 0.99, 1])) tlocs = np.arccos(rlocs) # Conversion to polar angles gl1 = gf.FixedLocator(tlocs) # Positions tf1 = gf.DictFormatter(dict(list(zip(tlocs, list(map(str, rlocs)))))) # Set standard deviation labels gl2 = gf.FixedLocator(std_level) # format each label with 2 decimal places format_string = list(map(lambda x: "{0:0.2f}".format(x), std_level)) index = np.where(std_level == self.refstd)[0][0] format_string[index] = label tf2 = gf.DictFormatter(dict(list(zip(std_level, format_string)))) # Use customized GridHelperCurveLinear to define curved axis ghelper = fa.GridHelperCurveLinear( tr, extremes=( 0, np.pi / 2, # 1st quadrant only self.smin, self.smax), grid_locator1=gl1, tick_formatter1=tf1, grid_locator2=gl2, tick_formatter2=tf2) # Create graphical axes ax = fa.FloatingSubplot(self.fig, rect, grid_helper=ghelper) self.fig.add_subplot(ax) # Adjust axes for Correlation 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("right") ax.axis["top"].label.set_axis_direction("top") ax.axis["top"].label.set_text("Correlation") # Standard deviation ("X axis") ax.axis["left"].set_axis_direction("bottom") # Standard deviation ("Y axis") ax.axis["right"].set_axis_direction("top") ax.axis["right"].toggle(ticklabels=True, label=True) ax.axis["right"].major_ticklabels.set_axis_direction("left") ax.axis["right"].label.set_text("Standard deviation (Normalized)") # Set font sizes, tick sizes, and padding ax.axis['top', 'right'].label.set_fontsize(18) ax.axis['top', 'right', 'left'].major_ticklabels.set_fontsize(16) ax.axis['top', 'right', 'left'].major_ticks.set_ticksize(10) ax.axis['top', 'right', 'left'].major_ticklabels.set_pad(8) ax.axis['top', 'right'].label.set_pad(6) # Bottom axis is not needed ax.axis["bottom"].set_visible(False) self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point stddev contour t = np.linspace(0, np.pi / 2) r = np.zeros_like(t) + self.refstd h, = self.ax.plot(t, r, linewidth=1, linestyle=(0, (9, 5)), color='black', zorder=1) # Set aspect ratio self.ax.set_aspect('equal') # Store the reference line self.referenceLine = h # Collect sample points for latter use (e.g. legend) self.modelMarkerSet = [] # Set number for models outside axes self.modelOutside = -1
def __init__(self, refstd, 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, [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 = 1.5 * self.refstd ghelper = FA.GridHelperCurveLinear( tr, extremes=(0, np.pi / 2, self.smin, self.smax), # 1stquadrant 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'].label.set_text('Standard deviation') 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*', rem by saeed # ls='', ms=10, label=label) rem by saeed # t = np.linspace(0, np.pi/2) rem by saeed # r = np.zeros_like(t) + self.refstd rem by saeed # self.ax.plot(t,r, 'k--', label='_') rem by saeed for ip in range(len(rlocs)): x = [self.smin, self.smax] y = [np.arccos(rlocs[ip]), np.arccos(rlocs[ip])] self.ax.plot(y, x, 'grey', linewidth=0.25) # Collect sample points for latter use (e.g. legend) # self.samplePoints = [l] rem by saeed self.samplePoints = [] # add by saeed
def setup_axes(self, fig, rect=111): """Set up Taylor diagram axes, i.e. single quadrant polar plot, using mpl_toolkits.axisartist.floating_axes. Wouldn't the ideal be to define its own non-linear transformation, so that coordinates are directly r=stddev and theta=correlation? I guess it would allow """ from matplotlib.projections import PolarAxes import mpl_toolkits.axisartist.floating_axes as FA import mpl_toolkits.axisartist.grid_finder as GF 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)))) ghelper = FA.GridHelperCurveLinear(tr, extremes=(0,NP.pi/2, # 1st quadrant 0,1.5*self.ref.std()), grid_locator1=gl1, tick_formatter1=tf1, ) 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 # Grid ax.grid() self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and stddev contour print("Reference std:", self.ref.std()) self.ax.plot([0],self.ref.std(),'ko', label='_') t = NP.linspace(0,NP.pi/2) r = NP.zeros_like(t) + self.ref.std() self.ax.plot(t,r,'k--', label='_') return self.ax
def __init__(self, refstd, fig=None, rect=111, label='_', norm=False, full=False, grid=True): """Set up Taylor diagram axes, i.e. polar plot, using mpl_toolkits.axisartist.floating_axes. refstd is the reference standard deviation to be compared to. norm : flag to normalize with respect to refstd. full : flag to create single quadrant or semi-circle """ from matplotlib.projections import PolarAxes as _PolarAxes import mpl_toolkits.axisartist.floating_axes as _FA import mpl_toolkits.axisartist.grid_finder as _GF self.refstd = refstd # Reference standard deviation self.norm = norm # Normalized or Absolute self.full = full # Full or Single-quadrant Taylor self.grid = grid # Cyan grid-lines at correlation theta tr = _PolarAxes.PolarTransform() # Correlation labels rlocs = _np.concatenate((_np.arange(10)/10.,[0.95,0.99])) if self.full: rlocs = _np.concatenate([-1.*_np.flipud(rlocs)[:-1],rlocs]) 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 and labels self.smin = 0 if self. norm: self.smax = 1.5 slocs = _np.arange(self.smax*10)[::2]/10. gl2 = _GF.FixedLocator(slocs) tf2 = _GF.DictFormatter(dict(zip(slocs, map(str,slocs)))) else: self.smax = 1.5*self.refstd gl2 = None tf2 = None self.ext_max = _np.pi if self.full else _np.pi/2. ghelper = _FA.GridHelperCurveLinear(tr, extremes=(0.,self.ext_max, self.smin,self.smax), grid_locator1=gl1, tick_formatter1=tf1, grid_locator2=gl2, tick_formatter2=tf2, ) if fig is None: fig = _plt.figure() self.fig = fig 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["top"].label.set_fontsize(12) ax.axis["top"].label.set_fontweight("normal") ax.axis["left"].set_axis_direction("bottom") # "X axis" ax.axis["left"].label.set_text("Normalized Standard Deviation" if self.norm else "Standard Deviation") ax.axis["left"].label.set_fontsize(12) ax.axis["left"].label.set_fontweight("normal") ax.axis["right"].set_axis_direction("top") # "Y axis" ax.axis["right"].toggle(ticklabels=True) if self.full: ax.axis["right"].major_ticklabels.set_axis_direction("bottom") ax.axis["bottom"].toggle(ticklabels=False) ax.axis["bottom"].set_axis_direction("bottom") else: 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], 1.0 if self.norm else self.refstd, 'k*', ls='', ms=10, label=label) t = _np.linspace(0, self.ext_max) r = _np.zeros_like(t) + ( 1.0 if self.norm else self.refstd ) self.ax.plot(t,r, 'k--', label='_') # Collect sample points for latter use (e.g. legend) self.samplePoints = [l] # Add 0 line if full Taylor if self.full: r = _np.linspace(0.,self.smax) t = _np.zeros_like(r) + _np.pi/2. self.ax.plot(t,r,'k--',label='_') # Add cyan radii at all correlations: if self.grid: r = _np.linspace(0.,self.smax) for th in tlocs: th_deg = 180.*th/_np.pi if not (20. < th_deg < 160. and th_deg != 90.): continue t = _np.zeros_like(r) + th self.ax.plot(t,r,'c-',label='_') return
def __init__(self, refstd, refcorrcoef=1.0, fig=None, rect=111, label='_', srange=(0, 1.5)): """Set up Taylor diagram axes, i.e. single quadrant polar plot, using `mpl_toolkits.axisartist.floating_axes`. Parameters: * refstd: reference standard deviation to be compared to * fig: input Figure or None * rect: subplot definition * label: reference label * srange: stddev axis extension, in units of *refstd* """ 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 (in units of reference stddev) self.smin = srange[0] * self.refstd self.smax = srange[1] * 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 self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and stddev contour l, = self.ax.plot(NP.arccos(refcorrcoef), 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 __init__(self, true, fig=None, rect=111, label='_', srange=(0, 1.5), extend=False, axis_fontdict: dict = None): """ Set up Taylor diagram axes, i.e. single quadrant polar plot, using `mpl_toolkits.axisartist.floating_axes`. Parameters: :refstd: reference standard deviation to be compared to :fig: input Figure or None :rect: subplot definition :label: reference label :srange: stddev axis extension, in units of *refstd* :extend: extend diagram to negative correlations :param axis_fontdict: dictionary must consist of at least three dictionaries 'left', 'right', 'top' """ #self.refstd = refstd # Reference standard deviation self.refstd = np.std(true) tr = PolarAxes.PolarTransform() # Correlation labels rlocs = np.array([0, 0.2, 0.4, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 1]) if extend: # Diagram extended to negative correlations self.tmax = np.pi rlocs = np.concatenate((-rlocs[:0:-1], rlocs)) else: # Diagram limited to positive correlations self.tmax = np.pi / 2 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 (in units of reference stddev) self.smin = srange[0] * self.refstd self.smax = srange[1] * self.refstd ghelper = FA.GridHelperCurveLinear(tr, extremes=(0, self.tmax, 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['top'].label.set_fontsize(axis_fontdict['top'].get( 'fontsize', 18)) ax.axis['top'].label.set_color(axis_fontdict['top'].get('color', 'k')) ax.axis['top'].major_ticklabels.set_fontsize(axis_fontdict['top'].get( 'ticklabel_fs', 10)) ax.axis["left"].set_axis_direction("bottom") # "X axis" ax.axis["left"].label.set_text("Standard deviation") ax.axis['left'].label.set_fontsize(axis_fontdict['bottom'].get( 'fontsize', 18)) ax.axis['left'].label.set_color(axis_fontdict['bottom'].get( 'color', 'k')) ax.axis['left'].major_ticklabels.set_fontsize( axis_fontdict['bottom'].get('ticklabel_fs', 10)) ax.axis["right"].set_axis_direction("top") # "Y-axis" ax.axis["right"].toggle(ticklabels=True) ax.axis['right'].label.set_fontsize(axis_fontdict['left'].get( 'fontsize', 18)) ax.axis['right'].label.set_color(axis_fontdict['left'].get( 'color', 'k')) ax.axis['right'].major_ticklabels.set_fontsize( axis_fontdict['left'].get('ticklabel_fs', 10)) ax.axis["right"].major_ticklabels.set_axis_direction( "bottom" if extend else "left") if self.smin: ax.axis["bottom"].toggle(ticklabels=False, label=False) else: ax.axis["bottom"].set_visible(False) # Unused self._ax = ax # Graphical axes self.ax = ax.get_aux_axes(tr) # Polar coordinates # Add reference point and stddev contour l, = self.ax.plot([0], self.refstd, 'k*', ls='', ms=10, label=label) t = np.linspace(0, self.tmax) 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 __init__(self, refstd, 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 = 1.4 * 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) # for plot number > 9 ax = FA.FloatingSubplot(fig, rect[0], rect[1], rect[2], \ 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) # ms is the marker size 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 Taylor_diag(series, names, styles, colors): """ Taylor Diagram : obs is reference data sample in a full diagram (0 --> npi) -------------------------------------------------------------------------- Input: series - dict with all time series (lists) to analyze series[0] - is the observation, the reference by default. """ from matplotlib.projections import PolarAxes taylor_stats = np.array([ AnDA_Taylor_stats(series[i], series[list(series.keys())[0]]) for i in series.keys() ]) crmsd, corr, std = taylor_stats.T ref = std[0] rlocs = np.concatenate((np.arange(0, 10, 0.25), [0.95, 0.99])) str_rlocs = np.concatenate((np.arange(0, 10, 0.25), [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)))) str_locs2 = np.arange(0, 11, 0.5) tlocs2 = np.arange(0, 11, 0.5) # Conversion to polar angles g22 = GF.FixedLocator(tlocs2) tf2 = GF.DictFormatter(dict(zip(tlocs2, map(str, str_locs2)))) tr = PolarAxes.PolarTransform() smin = 0 smax = (120 / 100) * np.max(std) ghelper = FA.GridHelperCurveLinear( tr, extremes=( 0, np.pi / 2, # 1st quadrant smin, smax), grid_locator1=gl1, #grid_locator2=g11, tick_formatter1=tf1, tick_formatter2=tf2, ) fig = plt.figure(figsize=(10, 5), dpi=100) ax = FA.FloatingSubplot(fig, 111, grid_helper=ghelper) fig.add_subplot(ax) ax.axis["top"].set_axis_direction("bottom") 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 Coefficient") ax.axis["left"].set_axis_direction("bottom") ax.axis["left"].label.set_text("Standard Deviation") ax.axis["right"].set_axis_direction("top") ax.axis["right"].toggle(ticklabels=True, label=True) ax.axis["right"].set_visible(True) ax.axis["right"].major_ticklabels.set_axis_direction("bottom") ax.axis["right"].label.set_text("Standard Deviation") ax.axis["bottom"].set_visible(False) ax.grid(True) ax = ax.get_aux_axes(tr) t = np.linspace(0, np.pi / 2) r = np.zeros_like(t) + ref ax.plot(t, r, 'k--', label='_') rs, ts = np.meshgrid(np.linspace(smin, smax), np.linspace(0, np.pi / 2)) rms = np.sqrt(ref**2 + rs**2 - 2 * ref * rs * np.cos(ts)) CS = ax.contour(ts, rs, rms, cmap=cm.bone) plt.clabel(CS, inline=1, fontsize=10) ax.plot(np.arccos(0.9999), ref, 'k', marker='*', ls='', ms=10) aux = range(1, len(corr)) #colors = plt.matplotlib.cm.jet(np.linspace(0,1,len(corr))) for i in reversed(aux): ax.plot(np.arccos(corr[i]), std[i], c=colors[i], alpha=0.7, marker=styles[i], label="%s" % names[i]) #ax.text(np.arccos(corr[i]), std[i],"%s"%i) # inset axes.... '''axins = ax.inset_axes([1.1, 0, 0.3, 0.3]) def pol2cart(phi, rho): x = rho * np.cos(phi) y = rho * np.sin(phi) return(x, y) x = np.empty(len(aux)) y = np.empty(len(aux)) for i in reversed(aux): x[i-1], y[i-1] = pol2cart(np.arccos(corr[i]), std[i]) axins.plot(x[i-1], y[i-1], c=colors[i],alpha=0.7,marker=styles[i],label="%s" %names[i]) #axins.text(x[i-1], y[i-1],"%s"%i) # sub region of the original image x1, x2, y1, y2 = np.min(x)-(1/50)*np.min(x), np.max(x)+(1/50)*np.max(x),\ np.min(y)-(1)*np.min(y), np.max(y)+(1)*np.max(y) axins.set_xlim(x1,x2) axins.set_ylim(y1,y2) axins.set_xticks([]) axins.set_yticks([]) axins.set_xticklabels('') axins.set_yticklabels('')''' plt.legend(bbox_to_anchor=(1.5, 1), prop=dict(size='small'), loc='best')