def _rebuild_iso(self, sel=None): if not self.graph: return if sel is not None: g = self.graph ss = [p.plots[pp][0] for p in g.plots for pp in p.plots if pp == 'data{}'.format(self.group_id)] self._set_renderer_selection(ss, sel) # reg = self._cached_reg # # reg.user_excluded = sel # reg.error_calc_type = self.options.error_calc_method # reg.dirty = True # reg.calculate() self.analysis_group.dirty = True if self._plot_label: self._add_results_info(self.graph.plots[0], label=self._plot_label) else: self.analysis_group.calculate_isochron() reg = self.analysis_group.isochron_regressor fit = self.graph.plots[0].plots['fit{}'.format(self.group_id)][0] mi, ma = self.graph.get_x_limits() rxs = linspace(0, ma) rys = reg.predict(rxs) fit.index.set_data(rxs) fit.value.set_data(rys) if self.options.include_error_envelope: lci, uci = reg.calculate_error_envelope(rxs) if not hasattr(fit, 'error_envelope'): group = self.options.get_group(self.group_id) color = group.color ee = ErrorEnvelopeOverlay(component=fit, upper=uci, lower=lci, line_color=color) fit.underlays.append(ee) fit.error_envelope = ee else: fit.error_envelope.invalidate() fit.error_envelope.lower = lci fit.error_envelope.upper = uci
def _graph_hole_vs_j(self, x, y, r, reg, refresh): if self._individual_analyses_enabled: sel = [ i for i, (a, x, y, e) in enumerate(zip(*self._analyses)) if a.is_omitted() ] g = self.graph if not isinstance(g, Graph): g = Graph(container_dict={'bgcolor': self.plotter_options.bgcolor}) self.graph = g po = self.plotter_options ys = reg.ys xs = arctan2(x, y) yserr = reg.yserr lyy = ys - yserr uyy = ys + yserr a = max((abs(min(xs)), abs(max(xs)))) fxs = linspace(-a, a, 200) a = r * sin(fxs) b = r * cos(fxs) pts = vstack((a, b)).T fys = reg.predict(pts) use_ee = False if po.model_kind not in (MATCHING, BRACKETING, NN): use_ee = True try: l, u = reg.calculate_error_envelope(fxs, rmodel=fys) except BaseException: l, u = reg.calculate_error_envelope(pts, rmodel=fys) if not refresh: g.clear() p = g.new_plot( xtitle='Hole (Theta)', ytitle='J', # padding=[90, 5, 5, 40], padding=po.get_paddings()) p.bgcolor = po.plot_bgcolor add_axes_tools(g, p) def label_fmt(xx): return floatfmt(xx, n=2, s=4, use_scientific=True) p.y_axis.tick_label_formatter = label_fmt # plot fit line # plot0 == line if po.model_kind in (MATCHING, BRACKETING, NN): g.new_series(fxs, fys, render_style='connectedhold') else: line, _p = g.new_series(fxs, fys) if use_ee: ee = ErrorEnvelopeOverlay(component=line, xs=fxs, lower=l, upper=u) line.error_envelope = ee line.underlays.append(ee) miy = 100 may = -1 if self._individual_analyses_enabled: # plot the individual analyses # plot1 == scatter iscatter, iys = self._graph_individual_analyses() miy = min(iys) may = max(iys) # plot means # plot2 == scatter scatter, _ = g.new_series(xs, ys, yerror=yserr, type='scatter', marker_size=4, marker='diamond') ebo = ErrorBarOverlay(component=scatter, orientation='y') scatter.underlays.append(ebo) scatter.error_bars = ebo add_inspector(scatter, self._additional_info) ymi = min(lyy.min(), miy) yma = max(uyy.max(), may) g.set_x_limits(-3.5, 3.5) g.set_y_limits(ymi, yma, pad='0.1') if self._individual_analyses_enabled: # set metadata last because it will trigger a refresh self.suppress_metadata_change = True iscatter.index.metadata['selections'] = sel self.suppress_metadata_change = False if self._individual_analyses_enabled: # add a legend labels = [ ('plot1', 'Individual'), ('plot2', 'Mean'), ('plot0', 'Fit'), ] else: labels = [('plot0', 'Mean')] legend = ExplicitLegend(plots=self.graph.plots[0].plots, labels=labels) p.overlays.append(legend) else: plot = g.plots[0] s1 = plot.plots['plot2'][0] s1.yerror.set_data(yserr) s1.error_bars.invalidate() g.set_data(ys, plotid=0, series=2, axis=1) l1 = plot.plots['plot0'][0] l1.index.metadata['selections'] = sel g.set_data(fys, plotid=0, series=0, axis=1) if use_ee: l1.error_envelope.trait_set(xs=fxs, lower=l, upper=u) l1.error_envelope.invalidate() self.max_j = fys.max() self.min_j = fys.min()
def _graph_hole_vs_j(self, x, y, r, reg, refresh): sel = [i for i, a in enumerate(self.analyses) if a.is_omitted()] g = self.graph if not isinstance(g, Graph): g = Graph(container_dict={'bgcolor': self.plotter_options.bgcolor}) self.graph = g po = self.plotter_options xs = arctan2(x, y) ys = reg.ys a = max((abs(min(xs)), abs(max(xs)))) fxs = linspace(-a, a) a = r * sin(fxs) b = r * cos(fxs) pts = vstack((a, b)).T fys = reg.predict(pts) yserr = reg.yserr l, u = reg.calculate_error_envelope([[p] for p in pts], rmodel=fys) lyy = ys - yserr uyy = ys + yserr if not refresh: g.clear() p = g.new_plot(xtitle='Hole (Theta)', ytitle='J', # padding=[90, 5, 5, 40], padding=po.paddings()) p.bgcolor = po.plot_bgcolor p.y_axis.tick_label_formatter = lambda x: floatfmt(x, n=2, s=4, use_scientific=True) scatter, _ = g.new_series(xs, ys, yerror=yserr, type='scatter', marker='circle') ebo = ErrorBarOverlay(component=scatter, orientation='y') scatter.overlays.append(ebo) scatter.error_bars = ebo add_inspector(scatter, self._additional_info) line, _p = g.new_series(fxs, fys) ee = ErrorEnvelopeOverlay(component=line, xs=fxs, lower=l, upper=u) line.error_envelope = ee line.overlays.append(ee) # plot the individual analyses s, iys = self._graph_individual_analyses() s.index.metadata['selections'] = sel # s.index.metadata_changed = True ymi = min(lyy.min(), min(iys)) yma = max(uyy.max(), max(iys)) g.set_x_limits(-3.2, 3.2) else: plot = g.plots[0] s1 = plot.plots['plot0'][0] s1.yerror.set_data(yserr) s1.error_bars.invalidate() l1 = plot.plots['plot1'][0] l1.error_envelope.trait_set(xs=fxs, lower=l, upper=u) l1.error_envelope.invalidate() g.set_data(ys, plotid=0, series=0, axis=1) g.set_data(fys, plotid=0, series=1, axis=1) s2 = plot.plots['plot2'][0] iys = s2.value.get_data() ymi = min(fys.min(), lyy.min(), iys.min()) yma = max(fys.max(), uyy.max(), iys.max()) s2.index.metadata['selections'] = sel g.set_y_limits(ymi, yma, pad='0.1') self._model_sin_flux(fxs, fys)
def _plot_inverse_isochron(self, po, plot, pid): analyses = self.sorted_analyses # plot.padding_left = 75 refiso = analyses[0] self._ref_constants = refiso.arar_constants self._ref_j = refiso.j self._ref_age_scalar = refiso.arar_constants.age_scalar self._ref_age_units = refiso.arar_constants.age_units # try: # age, reg, data = calculate_isochron(analyses) # except TypeError: # return ec = self.options.error_calc_method self.analysis_group.isochron_age_error_kind = ec data = self.analysis_group.get_isochron_data() _, reg, (xs, ys, xerrs, yerrs) = data self._cached_data = data self._cached_reg = reg graph = self.graph u39 = u'\u00b3\u2079' u40 = u'\u2074\u2070' u36 = u'\u00b3\u2076' xtitle = u'{}Ar/{}Ar'.format(u39, u40) ytitle = u'{}Ar/{}Ar'.format(u36, u40) # xtitle = '39Ar/40Ar' # ytitle = '36Ar/40Ar' xtitle = '<sup>39</sup>Ar/<sub>40</sup>Ar' ytitle = '<sup>36</sup>Ar/<sub>40</sup>Ar' # for axis in (plot.x_axis, plot.y_axis): # axis.title_font = 'courier 15' # graph.set_x_title(xtitle, plotid=pid) # graph.set_y_title(ytitle, plotid=pid) # if '<sup>' in title or '<sub>' in title: self._set_ml_title(ytitle, pid, 'y') self._set_ml_title(xtitle, pid, 'x') p = graph.plots[pid] p.y_axis.title_spacing = 50 graph.set_grid_traits(visible=False) graph.set_grid_traits(visible=False, grid='y') scatter, _p = graph.new_series(xs, ys, xerror=ArrayDataSource(data=xerrs), yerror=ArrayDataSource(data=yerrs), type='scatter', marker='circle', bind_id=self.group_id, # selection_marker_size=5, # selection_color='green', marker_size=2) # self._scatter = scatter graph.set_series_label('data{}'.format(self.group_id)) eo = ErrorEllipseOverlay(component=scatter, reg=reg, fill=self.options.fill_ellipses) scatter.overlays.append(eo) # mi, ma = graph.get_x_limits() # ma = max(ma, max(xs)) # mi = min(mi, min(xs)) mi, ma = min(xs), max(xs) self.xma = max(self.xma, ma) self.xmi = min(self.xmi, mi) # print len(xs),mi,ma mi = 0 rxs = linspace(mi, ma) rys = reg.predict(rxs) graph.set_x_limits(min_=mi, max_=ma, pad='0.1') l, _ = graph.new_series(rxs, rys, color=scatter.color) graph.set_series_label('fit{}'.format(self.group_id)) l.index.set_data(rxs) l.value.set_data(rys) yma, ymi = max(rys), min(rys) try: self.ymis[pid] = min(self.ymis[pid], ymi) self.ymas[pid] = max(self.ymas[pid], yma) except IndexError: self.ymis.append(ymi) self.ymas.append(yma) print 'isochron regressor error type {}'.format(reg.error_calc_type) lci, uci = reg.calculate_error_envelope(l.index.get_data()) ee = ErrorEnvelopeOverlay(component=l, upper=uci, lower=lci) l.underlays.append(ee) l.error_envelope = ee def ad(i, x, y, ai): a = ai.isotopes['Ar39'].get_interference_corrected_value() b = ai.isotopes['Ar40'].get_interference_corrected_value() r = a / b v = r.nominal_value e = r.std_dev try: pe = '({:0.2f}%)'.format(e / v * 100) except ZeroDivisionError: pe = '(Inf%)' return u'39Ar/40Ar = {} {}{} {}'.format(floatfmt(v, n=6), PLUSMINUS, floatfmt(e, n=7), pe) if self.group_id == 0: if self.options.display_inset: self._add_inset(plot, xs, ys, reg) if self.options.show_nominal_intercept: self._add_atm_overlay(plot) graph.add_vertical_rule(0, color='black') self._add_info(plot, reg, text_color=scatter.color) if po.show_labels: self._add_point_labels(scatter) self._add_scatter_inspector(scatter, additional_info=ad) # d = lambda a, b, c, d: self.update_index_mapper(a, b, c, d) p.index_mapper.on_trait_change(self.update_index_mapper, 'updated')
def _add_error_envelope_overlay(self, line): o = ErrorEnvelopeOverlay(component=weakref.ref(line)()) line.overlays.append(o) line.error_envelope = o
def _add_error_envelope_overlay(self, line): o = ErrorEnvelopeOverlay(component=line) line.underlays.append(o) line.error_envelope = o
def _add_filter_bounds_overlay(self, line): o = ErrorEnvelopeOverlay(component=line, use_region=True, color=(1)) line.underlays.append(o) line.filter_bounds = o o.visible = False return o
def _plot_inverse_isochron(self, po, plot, pid): opt = self.options self.analysis_group.isochron_age_error_kind = opt.error_calc_method _, _, reg = self.analysis_group.get_isochron_data(exclude_non_plateau=opt.exclude_non_plateau) graph = self.graph xtitle = '<sup>39</sup>Ar/<sup>40</sup>Ar' ytitle = '<sup>36</sup>Ar/<sup>40</sup>Ar' # self._set_ml_title(ytitle, pid, 'y') # self._set_ml_title(xtitle, pid, 'x') graph.set_y_title(ytitle, plotid=pid) graph.set_x_title(xtitle, plotid=pid) p = graph.plots[pid] p.y_axis.title_spacing = 50 graph.set_grid_traits(visible=False) graph.set_grid_traits(visible=False, grid='y') group = opt.get_group(self.group_id) color = group.color marker = opt.marker marker_size = opt.marker_size scatter, _p = graph.new_series(reg.xs, reg.ys, xerror=ArrayDataSource(data=reg.xserr), yerror=ArrayDataSource(data=reg.yserr), type='scatter', marker=marker, selection_marker=marker, selection_marker_size=marker_size, bind_id=self.group_id, color=color, marker_size=marker_size) graph.set_series_label('data{}'.format(self.group_id)) eo = ErrorEllipseOverlay(component=scatter, reg=reg, border_color=color, fill=opt.fill_ellipses, kind=opt.ellipse_kind) scatter.overlays.append(eo) ma = max(reg.xs) self.xma = max(self.xma, ma) self.xmi = min(self.xmi, min(reg.xs)) mi = 0 rxs = linspace(mi, ma * 1.1) rys = reg.predict(rxs) graph.set_x_limits(min_=mi, max_=ma, pad='0.1') l, _ = graph.new_series(rxs, rys, color=color) graph.set_series_label('fit{}'.format(self.group_id)) l.index.set_data(rxs) l.value.set_data(rys) yma, ymi = max(rys), min(rys) try: self.ymis[pid] = min(self.ymis[pid], ymi) self.ymas[pid] = max(self.ymas[pid], yma) except IndexError: self.ymis.append(ymi) self.ymas.append(yma) if opt.include_error_envelope: lci, uci = reg.calculate_error_envelope(l.index.get_data()) ee = ErrorEnvelopeOverlay(component=l, upper=uci, lower=lci, line_color=color) l.underlays.append(ee) l.error_envelope = ee if opt.display_inset: self._add_inset(plot, reg) if self.group_id == 0: if opt.show_nominal_intercept: self._add_atm_overlay(plot) graph.add_vertical_rule(0, color='black') if opt.show_results_info: self._add_results_info(plot, text_color=color) if opt.show_info: self._add_info(plot) if opt.show_labels: self._add_point_labels(scatter) def ad(i, x, y, ai): a = ai.isotopes['Ar39'].get_interference_corrected_value() b = ai.isotopes['Ar40'].get_interference_corrected_value() r = a / b v = nominal_value(r) e = std_dev(r) try: pe = '({:0.2f}%)'.format(e / v * 100) except ZeroDivisionError: pe = '(Inf%)' return u'39Ar/40Ar= {} {}{} {}'.format(floatfmt(v, n=6), PLUSMINUS, floatfmt(e, n=7), pe) self._add_scatter_inspector(scatter, additional_info=ad) p.index_mapper.on_trait_change(self.update_index_mapper, 'updated') # sel = self._get_omitted_by_tag(self.analyses) # self._rebuild_iso(sel) self.replot()