Beispiel #1
0
    def plot(self, ax=None, pt_size=9, color='0'):
        """
        Set up uncertainty distribution plot

        :param ax: matplotlib axes object
        :param pt_size: character point size
        :param color: colour
        :return: none
        """
        if not ax:
            ax = plt.subplot(1, 1, 1)

        linewidth = .5 * pt_size / 9
        t = self.t([.003, .16, .5, .84, .997])
        p = np.searchsorted(self.ts, t) - 1

        max_ticks = 3
        xt = gm.ticks(np.append(0, t), max_ticks)
        max_t = np.max(xt)
        max_text = cst.str_age(max_t, simple=True)
        a = max_text.split(' ')
        xt_units = float(a[0]) / max_t * xt
        xt_label = ['{:g}'.format(e) for e in xt_units]
        xt_label[-1] = "      " + xt_label[-1] + " " + a[
            1]  # add unit to last label, e.g. "Ga"

        ax.plot(self.ts, self.pdf, lw=linewidth * 1.5, color=color)
        ax.patch.set_facecolor(
            'none')  # make region transparent over background graphics
        ax.fill_between(self.ts[p[1]:p[3]],
                        self.pdf[p[1]:p[3]],
                        0,
                        color=color,
                        alpha=0.35,
                        edgecolor=color,
                        lw=linewidth)  #'.7'
        ax.fill_between(self.ts[p[2]:p[2] + 1],
                        self.pdf[p[2]:p[2] + 1],
                        edgecolor=color,
                        lw=linewidth,
                        alpha=.5)

        ax.get_yaxis().set_visible(False)
        for e in ['right', 'left', 'top']:
            ax.spines[e].set_visible(False)
        ax.spines['bottom'].set_linewidth(linewidth)
        ax.spines['bottom'].set_color(color)

        ax.set_xbound(lower=0, upper=xt[1])
        ax.set_xticks(xt)
        ax.tick_params(axis='x',
                       which='both',
                       width=linewidth,
                       length=pt_size * .2,
                       pad=pt_size * .1,
                       color=color)
        ax.tick_params(axis='x', which='minor', length=pt_size * .1)
        ax.xaxis.set_minor_locator(ticker.AutoMinorLocator())
        ax.set_xticklabels(xt_label, fontsize=pt_size * .7,
                           color=color)  #,horizontalalignment='left')
Beispiel #2
0
 def test_str_age(self):
     self.assertEqual(cst.str_age(.314, .11, .14), '$314^{+110}_{-140}$ Ma')
     self.assertEqual(cst.str_age(.314, .11, .14, ga=True, mu=True),
                      '$\mu0.314^{+0.11}_{-0.14}$ Ga')
     self.assertEqual(cst.str_age(.314, simple=True), '314 Ma')
     self.assertEqual(cst.str_age(1.), '$1.00$ Ga')
     self.assertEqual(cst.str_age(1., simple=True), '1 Ga')
     self.assertEqual(cst.str_age(.314, .11, .14, sf=2),
                      '$310^{+100}_{-100}$ Ma')
Beispiel #3
0
    def plot_isochrons(self):
        """
        Overplot predefined isochrons with annotations

        :return: none
        """

        isochrons = [(abs(float(e.rstrip('ash'))), 'h' in e, 'a' in e, 's'
                      in e) for e in self.isochrons.split(',')]

        for t, hide, above, small in isochrons:
            a0 = self.cf.a0(t)
            iso = self.pf.getisochron(self.presentation, a0, self.ef)
            d10 = np.log10(iso['d'])
            self.ax.plot(d10, iso['y'], color=self.grey[0], lw=.5)

            q = gm.where(
                np.abs(np.log10(iso['y']) - (self.yrange[1] - .1)) < .1)
            if not q or (d10[q[0]] <
                         self.xrange[0]):  # (d10[q[0][0]] < self.xrange[0]):
                q = gm.where(
                    abs(d10 - np.max([self.xrange[0] + .15, d10[0]])) < .1)

            if q and not hide:
                sx = np.mean(d10[q])
                sy = np.log10(self.pf.evaluate(self.presentation, 10**sx,
                                               a0)) - .05
                y_factor = self.data_aspect
                th = np.rad2deg(
                    np.arctan2(
                        np.log10(
                            self.pf.evaluate(self.presentation, 10**(sx + .3),
                                             a0)) - sy, .3 * y_factor))

                self.ax.text(sx,
                             10**sy,
                             cst.str_age(t, simple=True),
                             color=self.grey[0],
                             size=self.scaled_pt_size * (.5 if small else .7),
                             rotation=th,
                             rotation_mode='anchor',
                             verticalalignment='bottom' if above else 'top',
                             horizontalalignment='left',
                             bbox=dict(facecolor='none',
                                       edgecolor='none',
                                       boxstyle='square,pad=0.5'))
Beispiel #4
0
    def overplot(self, cps):
        """
        Add overplot elements into figure

        :param cps: Craterplotset instance
        :return: none
        """
        if not self.cratercount or self.hide: return

        p = self.cratercount.getplotdata(
            cps.presentation,
            self.binning,
            range=self.range,
            resurfacing=self.resurf_showall
            if self.resurf and self.type == 'c-fit' else None,
            pf=cps.pf)

        self.n = p['n']
        self.n_event = p['n_event']
        legend_label = []

        if self.error_bars:
            cps.ax.errorbar(np.log10(p['d']),
                            p['y'],
                            yerr=p['err'],
                            fmt='none',
                            linewidth=.7,
                            ecolor=cps.grey[0])

        if self.type in ['c-fit', 'd-fit', 'poisson', 'b-poisson']:
            self.calculate_age(cps)

            if self.isochron:
                iso = cps.pf.getisochron(cps.presentation, self.a0[0], cps.ef)
                cps.ax.plot(np.log10(iso['d']),
                            iso['y'],
                            label=None,
                            color=cps.grey[0],
                            lw=.4,
                            zorder=.9)

            expansion = np.array([.99, 1.01])
            fit = cps.pf.getplotdata(cps.presentation,
                                     self.a0[0],
                                     range=self.range * expansion)
            cps.ax.plot(np.log10(fit['d']),
                        fit['y'],
                        label='fit',
                        color=cps.palette[self.colour],
                        lw=.7)

            if self.display_age:
                st = cst.str_age(self.t[0],
                                 self.t[2] - self.t[0],
                                 self.t[0] - self.t[1],
                                 cps.sig_figs,
                                 mu=cps.mu)
                xy = cps.data_to_axis((np.log10(fit['d'][0]), fit['y'][0]))
                x, y = xy + 0.02 * np.ones(2) * (
                    -1 if self.age_left else 1) + np.array(self.offset_age) / (
                        cps.decades[0] * 20)  #(cps.decades[0]*10).
                cps.ax.text(
                    x,
                    y,
                    st,
                    transform=cps.ax.transAxes,
                    color=cps.palette[self.colour],
                    size=cps.scaled_pt_size * 1.2,
                    horizontalalignment='right' if self.age_left else 'left',
                )

                if self.type in ['poisson', 'b-poisson']:
                    text_extent = TextPath(
                        (0, 0), st,
                        size=cps.scaled_pt_size * 1.2).get_extents()
                    h, w = text_extent.height, text_extent.width
                    f = 1 / (cps.cm2inch *
                             (cps.position[2] - cps.position[0]) * 100
                             )  #conversion for axes coord
                    offset = self.pdf.offset(
                        self.age_left
                    )  # normalised units of mini-plot width in +x direction
                    box = np.array([
                        .12, .05
                    ]) * cps.pt_size / 9.  # dimensions of plot box

                    if self.age_left:  # offset from string write position
                        dx = -(f * w + .03) + (-1 + offset) * box[0]
                    else:
                        dx = f * w + .03 + offset * box[0]
                    dy = f * h / 2

                    pos = np.array(
                        [x + dx, y - dy, x + dx + box[0], y - dy + box[1]])
                    pos2 = cps.axis_to_fig(pos)
                    pos3 = np.concatenate([pos2[0:2], pos2[2:4] - pos2[0:2]])
                    ax = cps.fig.add_axes(pos3)
                    self.pdf.plot(ax,
                                  pt_size=cps.scaled_pt_size,
                                  color=cps.palette[self.colour])

            if '#' in cps.legend:
                if self.cratercount.buffered:
                    legend_label += ['{:.1f}'.format(self.n_event)]
                else:
                    if np.abs(self.n_event - self.n) < .001:
                        legend_label += ['{:0g}'.format(self.n)]
                    else:
                        legend_label += [
                            '{0:.1f} (of {1:d})'.format(self.n, self.n_event)
                        ]
                legend_label[-1] += " craters"
            if 'r' in cps.legend:
                if not self.cratercount.prebinned and self.type in [
                        'poisson', 'b-poisson'
                ]:
                    r = self.range
                else:
                    r = gm.range(
                        self.cratercount.generate_bins(self.binning,
                                                       self.range,
                                                       expand=False))
                legend_label += [cst.str_diameter_range(r)]
            if 'N' in cps.legend:
                legend_label += [
                    'N({0:0g})'.format(cps.ref_diameter) + '$=' +
                    gm.scientific_notation(self.n_d, sf=3) + '$ km$^{-2}$'
                ]

        if self.type == 'data':
            if 'n' in cps.legend:
                legend_label += [
                    self.name if self.name != '' else gm.filename(
                        self.source, "n")
                ]
            if 'a' in cps.legend:
                legend_label += [
                    '$' + gm.scientific_notation(self.cratercount.area, sf=3) +
                    '$ km$^{2}$'
                ]

        cps.ax.plot(np.log10(p['d']),
                    p['y'],
                    label=', '.join(legend_label) if legend_label else None,
                    **cps.marker_def[self.psym],
                    ls='',
                    color=cps.palette[self.colour],
                    markeredgewidth=.5)