Example #1
0
    def update(self):
        scores = self.pred_scores[self.vis_image_index]
        im = self.dataset[self.vis_image_index][0]  # fastai Image object

        _, sort_order = self._list_sort(scores, reverse=True)
        pred_labels_str = ""
        for i in sort_order:
            pred_labels_str += f"{self.labels[i]} ({scores[i]:3.2f})\n"
        self.w_pred_labels.value = str(pred_labels_str)

        self.w_image_header.value = f"Image index: {self.vis_image_index}"

        self.w_img.value = im._repr_png_()
        # Fix the width of the image widget and adjust the height
        self.w_img.layout.height = (
            f"{int(self.IM_WIDTH * (im.size[1]/im.size[0]))}px")

        self.w_gt_label.value = str(
            self.labels[self.dataset[self.vis_image_index][1]])

        self.w_filename.value = str(
            self.dataset.items[self.vis_image_index].name)
        self.w_path.value = str(
            self.dataset.items[self.vis_image_index].parent)
        bqpyplot.clear()
        bqpyplot.bar(
            self.labels,
            scores,
            align="center",
            alpha=1.0,
            color=np.abs(scores),
            scales={"color": bqplot.ColorScale(scheme="Blues", min=0)},
        )
Example #2
0
    def update_ui(self):
        pred_label = self.pred_labels[self.vis_image_index]
        img_obj = self.dataset.images[self.vis_image_index]
        scores = self.pred_scores[self.vis_image_index]

        self.w_image_header.value = "Image index: {}".format(
            self.vis_image_index)
        self.w_img.value = wImread(img_obj, self.context)
        self.w_gt_label.value = self.dataset.get_labels_for_image(
            img_obj)[0].name
        self.w_pred_label.value = str(pred_label)
        self.w_pred_score.value = str(
            self.pred_scores[self.vis_image_index,
                             self.label_to_id[pred_label]])
        self.w_index.value = str(self.vis_image_index)
        self.w_filename.value = img_obj.name
        self.w_path.value = img_obj.storage_path
        bqPyplot.clear()
        bqPyplot.bar(
            self.labels,
            scores,
            align='center',
            alpha=1.0,
            color=np.abs(scores),
            scales={'color': bqplot.ColorScale(scheme='Blues', min=0)})
 def updateUI(self):
     predLabel = self.predLabels[self.visImageIndex]
     imgObj = self.dataset.images[self.visImageIndex]
     scores = self.predScores[self.visImageIndex]
     self.wImageHeader.value = "Image index: {}".format(self.visImageIndex)
     self.wImg.value = wImread(imgObj, self.imgOrigDir)
     self.wGtLabel.value = imgObj.label
     self.wPredLabel.value = str(self.lutId2Label[predLabel])
     self.wPredScore.value = str(self.predScores[self.visImageIndex,
                                                 predLabel])
     self.wIndex.value = str(self.visImageIndex)
     self.wFilename.value = imgObj.filename
     bqPyplot.clear()
     bqPyplot.bar(
         self.labels,
         scores,
         align='center',
         alpha=1.0,
         color=np.abs(scores),
         scales={'color': bqplot.ColorScale(scheme='Blues', min=0)})
Example #4
0
    def vue_do_aper_phot(self, *args, **kwargs):
        if self._selected_data is None or self._selected_subset is None:
            self.result_available = False
            self.results = []
            self.plot_available = False
            self.radial_plot = ''
            self.hub.broadcast(SnackbarMessage(
                "No data for aperture photometry", color='error', sender=self))
            return

        data = self._selected_data
        reg = self._selected_subset

        try:
            comp = data.get_component(data.main_components[0])
            try:
                bg = float(self.background_value)
            except ValueError:  # Clearer error message
                raise ValueError('Missing or invalid background value')
            comp_no_bg = comp.data - bg

            # TODO: Use photutils when it supports astropy regions.
            if not isinstance(reg, RectanglePixelRegion):
                aper_mask = reg.to_mask(mode='exact')
            else:
                # TODO: https://github.com/astropy/regions/issues/404 (moot if we use photutils?)
                aper_mask = reg.to_mask(mode='subpixels', subpixels=32)
            npix = np.sum(aper_mask) * u.pix
            img = aper_mask.get_values(comp_no_bg, mask=None)
            aper_mask_stat = reg.to_mask(mode='center')
            comp_no_bg_cutout = aper_mask_stat.cutout(comp_no_bg)
            img_stat = aper_mask_stat.get_values(comp_no_bg, mask=None)
            include_pixarea_fac = False
            include_counts_fac = False
            include_flux_scale = False
            if comp.units:
                img_unit = u.Unit(comp.units)
                img = img * img_unit
                img_stat = img_stat * img_unit
                bg = bg * img_unit
                comp_no_bg_cutout = comp_no_bg_cutout * img_unit
                if u.sr in img_unit.bases:  # TODO: Better way to detect surface brightness unit?
                    try:
                        pixarea = float(self.pixel_area)
                    except ValueError:  # Clearer error message
                        raise ValueError('Missing or invalid pixel area')
                    if not np.allclose(pixarea, 0):
                        include_pixarea_fac = True
                if img_unit != u.count:
                    try:
                        ctfac = float(self.counts_factor)
                    except ValueError:  # Clearer error message
                        raise ValueError('Missing or invalid counts conversion factor')
                    if not np.allclose(ctfac, 0):
                        include_counts_fac = True
                try:
                    flux_scale = float(self.flux_scaling)
                except ValueError:  # Clearer error message
                    raise ValueError('Missing or invalid flux scaling')
                if not np.allclose(flux_scale, 0):
                    include_flux_scale = True
            rawsum = np.nansum(img)
            d = {'id': 1,
                 'xcenter': reg.center.x * u.pix,
                 'ycenter': reg.center.y * u.pix}
            if data.coords is not None:
                d['sky_center'] = data.coords.pixel_to_world(reg.center.x, reg.center.y)
            else:
                d['sky_center'] = None
            d.update({'background': bg,
                      'npix': npix})
            if include_pixarea_fac:
                pixarea = pixarea * (u.arcsec * u.arcsec / u.pix)
                pixarea_fac = npix * pixarea.to(u.sr / u.pix)
                d.update({'aperture_sum': rawsum * pixarea_fac,
                          'pixarea_tot': pixarea_fac})
            else:
                d.update({'aperture_sum': rawsum,
                          'pixarea_tot': None})
            if include_counts_fac:
                ctfac = ctfac * (rawsum.unit / u.count)
                sum_ct = rawsum / ctfac
                d.update({'aperture_sum_counts': sum_ct,
                          'aperture_sum_counts_err': np.sqrt(sum_ct.value) * sum_ct.unit,
                          'counts_fac': ctfac})
            else:
                d.update({'aperture_sum_counts': None,
                          'aperture_sum_counts_err': None,
                          'counts_fac': None})
            if include_flux_scale:
                flux_scale = flux_scale * rawsum.unit
                d.update({'aperture_sum_mag': -2.5 * np.log10(rawsum / flux_scale) * u.mag,
                          'flux_scaling': flux_scale})
            else:
                d.update({'aperture_sum_mag': None,
                          'flux_scaling': None})

            # Extra stats beyond photutils.
            d.update({'mean': np.nanmean(img_stat),
                      'stddev': np.nanstd(img_stat),
                      'median': np.nanmedian(img_stat),
                      'min': np.nanmin(img_stat),
                      'max': np.nanmax(img_stat),
                      'data_label': data.label,
                      'subset_label': reg.meta.get('label', ''),
                      'timestamp': Time(datetime.utcnow())})

            # Attach to app for Python extraction.
            if (not hasattr(self.app, '_aper_phot_results') or
                    not isinstance(self.app._aper_phot_results, QTable)):
                self.app._aper_phot_results = _qtable_from_dict(d)
            else:
                try:
                    d['id'] = self.app._aper_phot_results['id'].max() + 1
                    self.app._aper_phot_results.add_row(d.values())
                except Exception:  # Discard incompatible QTable
                    d['id'] = 1
                    self.app._aper_phot_results = _qtable_from_dict(d)

            # Radial profile
            reg_bb = reg.bounding_box
            reg_ogrid = np.ogrid[reg_bb.iymin:reg_bb.iymax, reg_bb.ixmin:reg_bb.ixmax]
            radial_dx = reg_ogrid[1] - reg.center.x
            radial_dy = reg_ogrid[0] - reg.center.y
            radial_r = np.hypot(radial_dx, radial_dy).ravel()  # pix
            radial_img = comp_no_bg_cutout.ravel()
            if comp.units:
                y_data = radial_img.value
                y_label = radial_img.unit.to_string()
            else:
                y_data = radial_img
                y_label = 'Value'
            bqplt.clear()
            # NOTE: default margin in bqplot is 60 in all directions
            fig = bqplt.figure(1, title='Radial profile from Subset center',
                               fig_margin={'top': 60, 'bottom': 60, 'left': 40, 'right': 10},
                               title_style={'font-size': '12px'})  # TODO: Jenn wants title at bottom. # noqa
            bqplt.plot(radial_r, y_data, 'go', figure=fig, default_size=1)
            bqplt.xlabel(label='pix', mark=fig.marks[-1], figure=fig)
            bqplt.ylabel(label=y_label, mark=fig.marks[-1], figure=fig)

        except Exception as e:  # pragma: no cover
            self.result_available = False
            self.results = []
            self.plot_available = False
            self.radial_plot = ''
            self.hub.broadcast(SnackbarMessage(
                f"Aperture photometry failed: {repr(e)}", color='error', sender=self))

        else:
            # Parse results for GUI.
            tmp = []
            for key, x in d.items():
                if key in ('id', 'data_label', 'subset_label', 'background', 'pixarea_tot',
                           'counts_fac', 'aperture_sum_counts_err', 'flux_scaling', 'timestamp'):
                    continue
                if (isinstance(x, (int, float, u.Quantity)) and
                        key not in ('xcenter', 'ycenter', 'sky_center', 'npix',
                                    'aperture_sum_counts')):
                    x = f'{x:.4e}'
                    tmp.append({'function': key, 'result': x})
                elif key == 'sky_center' and x is not None:
                    tmp.append({'function': 'RA center', 'result': f'{x.ra.deg:.4f} deg'})
                    tmp.append({'function': 'Dec center', 'result': f'{x.dec.deg:.4f} deg'})
                elif key in ('xcenter', 'ycenter', 'npix'):
                    x = f'{x:.1f}'
                    tmp.append({'function': key, 'result': x})
                elif key == 'aperture_sum_counts' and x is not None:
                    x = f'{x:.4e} ({d["aperture_sum_counts_err"]:.4e})'
                    tmp.append({'function': key, 'result': x})
                elif not isinstance(x, str):
                    x = str(x)
                    tmp.append({'function': key, 'result': x})
            self.results = tmp
            self.result_available = True
            self.radial_plot = fig
            self.bqplot_figs_resize = [fig]
            self.plot_available = True
Example #5
0
def submit_clicked(b):
    
    with output_widget:
        output_widget.clear_output()
        print('Computing...')
        Map.default_style = {'cursor': 'wait'}

        try:
            admin1_id = admin1_widget.value
            admin2_id = admin2_widget.value
            band1 = first_band.value
            band2 = second_band.value
            selected_year = year_widget.value
            threshold = nd_threshold.value
            bands = band_combo.value.split('/')
            apply_fmask = fmask_widget.value
            palette = nd_color.value
            use_aoi = aoi_widget.value
            download = download_widget.value
            
            if use_aoi:
                if Map.user_roi is not None:
                    roi = Map.user_roi
                    layer_name = 'User drawn AOI'
                    geom = roi
                else:
                    output_widget.clear_output() 
                    print('No user AOI could be found.')
                    return
            else:
            
                statefp = ee.Feature(states.filter(ee.Filter.eq('NAME', admin1_id)).first()).get('STATEFP')
                roi = fc.filter(ee.Filter.And(ee.Filter.eq('NAME', admin2_id), ee.Filter.eq('STATEFP', statefp)))
                layer_name = admin1_id + '-' + admin2_id
                geom = roi.geometry()


            Map.layers = Map.layers[:4]        
            Map.addLayer(ee.Image().paint(geom, 0, 2), {'palette': 'red'}, layer_name)  
            
            images = geemap.landsat_timeseries(roi=roi, start_year=1984, end_year=2020, start_date='01-01', end_date='12-31', apply_fmask=apply_fmask)
            nd_images = images.map(lambda img: img.normalizedDifference([band1, band2]))
            result_images = nd_images.map(lambda img: img.gt(threshold))

            selected_image = ee.Image(images.toList(images.size()).get(selected_year - 1984))
            selected_result_image = ee.Image(result_images.toList(result_images.size()).get(selected_year - 1984)).selfMask()
            
            vis_params = {
                'bands': bands,
                'min': 0,
                'max': 3000
            }
            
            Map.addLayer(selected_image, vis_params, 'Landsat ' + str(selected_year))
            Map.addLayer(selected_result_image, {'palette': palette}, 'Result ' + str(selected_year))

            
            def cal_area(img):
                pixel_area = img.multiply(ee.Image.pixelArea()).divide(1e4)
                img_area = pixel_area.reduceRegion(**{
                    'geometry': geom,
                    'reducer': ee.Reducer.sum(),
                    'scale': 1000,
                    'maxPixels': 1e12,
                    'bestEffort': True
                })
                return img.set({'area': img_area})
            
            areas = result_images.map(cal_area)
            stats = areas.aggregate_array('area').getInfo()
            x = list(range(1984, 2021))
            y = [item.get('nd') for item in stats]
            
            fig = plt.figure(1)
            fig.layout.height = '270px'
            plt.clear()
            plt.plot(x, y)
            plt.title('Temporal trend (1984-2020)')
            plt.xlabel('Year')
            plt.ylabel('Area (ha)')
            
            output_widget.clear_output()            

            plt.show()
            
            if download:
                out_dir = os.path.join(os.path.expanduser('~'), 'Downloads')
                out_name = 'chart_' + geemap.random_string() + '.csv'
                out_csv = os.path.join(out_dir, out_name)
                if not os.path.exists(out_dir):
                    os.makedirs(out_dir)
                with open(out_csv, 'w') as f:
                    f.write('year, area (ha)\n')
                    for index, item in enumerate(x):
                        line = '{},{:.2f}\n'.format(item, y[index])
                        f.write(line) 
                link = geemap.create_download_link(
                    out_csv, title="Click here to download the chart data: ")
                display(link)
    
        except Exception as e:
            print(e)
            print('An error occurred during computation.')        

        Map.default_style = {'cursor': 'default'}
Example #6
0
    def plot(self,
             x,
             y,
             plot_type=None,
             overlay=False,
             position='bottomright',
             min_width=None,
             max_width=None,
             min_height=None,
             max_height=None,
             **kwargs):
        """Creates a plot based on x-array and y-array data.

        Args:
            x (numpy.ndarray or list): The x-coordinates of the plotted line.
            y (numpy.ndarray or list): The y-coordinates of the plotted line.
            plot_type (str, optional): The plot type can be one of "None", "bar", "scatter" or "hist". Defaults to None.
            overlay (bool, optional): Whether to overlay plotted lines on the figure. Defaults to False.
            position (str, optional): Position of the control, can be ‘bottomleft’, ‘bottomright’, ‘topleft’, or ‘topright’. Defaults to 'bottomright'.
            min_width (int, optional): Min width of the widget (in pixels), if None it will respect the content size. Defaults to None.
            max_width (int, optional): Max width of the widget (in pixels), if None it will respect the content size. Defaults to None.
            min_height (int, optional): Min height of the widget (in pixels), if None it will respect the content size. Defaults to None.
            max_height (int, optional): Max height of the widget (in pixels), if None it will respect the content size. Defaults to None.            

        """
        if self.plot_widget is not None:
            plot_widget = self.plot_widget
        else:
            plot_widget = widgets.Output(layout={'border': '1px solid black'})
            plot_control = WidgetControl(widget=plot_widget,
                                         position=position,
                                         min_width=min_width,
                                         max_width=max_width,
                                         min_height=min_height,
                                         max_height=max_height)
            self.plot_widget = plot_widget
            self.plot_control = plot_control
            self.add_control(plot_control)

        if max_width is None:
            max_width = 500
        if max_height is None:
            max_height = 300

        if (plot_type is None) and ('markers' not in kwargs.keys()):
            kwargs['markers'] = 'circle'

        with plot_widget:
            try:
                fig = plt.figure(1, **kwargs)
                if max_width is not None:
                    fig.layout.width = str(max_width) + 'px'
                if max_height is not None:
                    fig.layout.height = str(max_height) + 'px'

                plot_widget.clear_output(wait=True)
                if not overlay:
                    plt.clear()

                if plot_type is None:
                    if 'marker' not in kwargs.keys():
                        kwargs['marker'] = 'circle'
                    plt.plot(x, y, **kwargs)
                elif plot_type == 'bar':
                    plt.bar(x, y, **kwargs)
                elif plot_type == 'scatter':
                    plt.scatter(x, y, **kwargs)
                elif plot_type == 'hist':
                    plt.hist(y, **kwargs)
                plt.show()

            except Exception as e:
                print(e)
                print("Failed to create plot.")