Exemple #1
0
def feature_byProperty(features, xProperties, seriesProperty, **kwargs):
    """Generates a Chart from a set of features. Plots property values of one or more features.
    Reference: https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturebyproperty

    Args:
        features (ee.FeatureCollection): The features to include in the chart.
        xProperties (list | dict): One of (1) a list of properties to be plotted on the x-axis; or (2) a (property, label) dictionary specifying labels for properties to be used as values on the x-axis.
        seriesProperty (str): The name of the property used to label each feature in the legend.

    Raises:
        Exception: If the provided xProperties is not a list or dict.
        Exception: If the chart fails to create.
    """
    try:
        df = ee_to_df(features)

        if isinstance(xProperties, list):
            x_data = xProperties
            y_data = df[xProperties].values
        elif isinstance(xProperties, dict):
            x_data = list(xProperties.values())
            y_data = df[list(xProperties.keys())].values
        else:
            raise Exception("xProperties must be a list or dictionary.")

        labels = list(df[seriesProperty])

        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = y_data.min()
            max_value = y_data.max()
            max_value = max_value + 0.2 * (max_value - min_value)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]
        if "legend_location" not in kwargs:
            legend_location = "top-left"
        else:
            legend_location = kwargs["legend_location"]

        if "display_legend" not in kwargs:
            display_legend = True
        else:
            display_legend = kwargs["display_legend"]

        fig = plt.figure(
            title=title,
            legend_location=legend_location,
        )

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        bar_chart = plt.bar(x=x_data,
                            y=y_data,
                            labels=labels,
                            display_legend=display_legend)

        bar_chart.type = "grouped"

        if "colors" in kwargs:
            bar_chart.colors = kwargs["colors"]

        if "xlabel" in kwargs:
            plt.xlabel(kwargs["xlabel"])
        if "ylabel" in kwargs:
            plt.ylabel(kwargs["ylabel"])
        plt.ylim(min_value, max_value)

        if "xlabel" in kwargs and ("ylabel" in kwargs):
            bar_chart.tooltip = Tooltip(
                fields=["x", "y"], labels=[kwargs["xlabel"], kwargs["ylabel"]])
        else:
            bar_chart.tooltip = Tooltip(fields=["x", "y"])

        plt.show()

    except Exception as e:
        raise Exception(e)
Exemple #2
0
def feature_groups(features, xProperty, yProperty, seriesProperty, **kwargs):
    """Generates a Chart from a set of features.
    Plots the value of one property for each feature.
    Reference:
    https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturegroups
    Args:
        features (ee.FeatureCollection): The feature collection to make a chart from.
        xProperty (str): Features labeled by xProperty.
        yProperty (str): Features labeled by yProperty.
        seriesProperty (str): The property used to label each feature in the legend.
    Raises:
        Exception: Errors when creating the chart.
    """

    try:
        df = ee_to_df(features)
        df[yProperty] = pd.to_numeric(df[yProperty])
        unique_series_values = df[seriesProperty].unique().tolist()
        new_column_names = []

        for value in unique_series_values:
            sample_filter = (df[seriesProperty] == value).map({
                True: 1,
                False: 0
            })
            column_name = str(yProperty) + "_" + str(value)
            df[column_name] = df[yProperty] * sample_filter
            new_column_names.append(column_name)

        if "labels" in kwargs:
            labels = kwargs["labels"]
        else:
            labels = [str(x) for x in unique_series_values]

        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = df[yProperty].to_numpy().min()
            max_value = df[yProperty].to_numpy().max()
            max_value = max_value + 0.2 * (max_value - min_value)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]
        if "legend_location" not in kwargs:
            legend_location = "top-left"
        else:
            legend_location = kwargs["legend_location"]

        x_data = list(df[xProperty])
        y_data = [df[x] for x in new_column_names]

        plt.bar(x_data, y_data)
        fig = plt.figure(
            title=title,
            legend_location=legend_location,
        )

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        if "display_legend" not in kwargs:
            display_legend = True
        else:
            display_legend = kwargs["display_legend"]

        bar_chart = plt.bar(x_data,
                            y_data,
                            labels=labels,
                            display_legend=display_legend)

        if "colors" in kwargs:
            bar_chart.colors = kwargs["colors"]

        if "xlabel" in kwargs:
            plt.xlabel(kwargs["xlabel"])
        if "ylabel" in kwargs:
            plt.ylabel(kwargs["ylabel"])
        plt.ylim(min_value, max_value)

        if "xlabel" in kwargs and ("ylabel" in kwargs):
            bar_chart.tooltip = Tooltip(
                fields=["x", "y"], labels=[kwargs["xlabel"], kwargs["ylabel"]])
        else:
            bar_chart.tooltip = Tooltip(fields=["x", "y"])

        plt.show()

    except Exception as e:
        raise Exception(e)
Exemple #3
0
def feature_histogram(features,
                      property,
                      maxBuckets=None,
                      minBucketWidth=None,
                      **kwargs):
    """
    Generates a Chart from a set of features.
    Computes and plots a histogram of the given property.
    - X-axis = Histogram buckets (of property value).
    - Y-axis = Frequency

    Reference:
    https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturehistogram

    Args:
        features  (ee.FeatureCollection): The features to include in the chart.
        property                   (str): The name of the property to generate the histogram for.
        maxBuckets       (int, optional): The maximum number of buckets (bins) to use when building a histogram;
                                          will be rounded up to a power of 2.
        minBucketWidth (float, optional): The minimum histogram bucket width, or null to allow any power of 2.

    Raises:
        Exception: If the provided xProperties is not a list or dict.
        Exception: If the chart fails to create.
    """
    import math

    if not isinstance(features, ee.FeatureCollection):
        raise Exception("features must be an ee.FeatureCollection")

    first = features.first()
    props = first.propertyNames().getInfo()
    if property not in props:
        raise Exception(
            f"property {property} not found. Available properties: {', '.join(props)}"
        )

    def nextPowerOf2(n):
        return pow(2, math.ceil(math.log2(n)))

    def grow_bin(bin_size, ref):
        while bin_size < ref:
            bin_size *= 2
        return bin_size

    try:

        raw_data = pd.to_numeric(
            pd.Series(features.aggregate_array(property).getInfo()))
        y_data = raw_data.tolist()

        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = raw_data.min()
            max_value = raw_data.max()

        data_range = max_value - min_value

        if not maxBuckets:
            initial_bin_size = nextPowerOf2(data_range / pow(2, 8))
            if minBucketWidth:
                if minBucketWidth < initial_bin_size:
                    bin_size = grow_bin(minBucketWidth, initial_bin_size)
                else:
                    bin_size = minBucketWidth
            else:
                bin_size = initial_bin_size
        else:
            initial_bin_size = math.ceil(data_range / nextPowerOf2(maxBuckets))
            if minBucketWidth:
                if minBucketWidth < initial_bin_size:
                    bin_size = grow_bin(minBucketWidth, initial_bin_size)
                else:
                    bin_size = minBucketWidth
            else:
                bin_size = initial_bin_size

        start_bins = (math.floor(min_value / bin_size) *
                      bin_size) - (bin_size / 2)
        end_bins = (math.ceil(max_value / bin_size) * bin_size) + (bin_size /
                                                                   2)

        if start_bins < min_value:
            y_data.append(start_bins)
        else:
            y_data[y_data.index(min_value)] = start_bins
        if end_bins > max_value:
            y_data.append(end_bins)
        else:
            y_data[y_data.index(max_value)] = end_bins

        num_bins = math.floor((end_bins - start_bins) / bin_size)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]

        fig = plt.figure(title=title)

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        if "xlabel" not in kwargs:
            xlabel = ""
        else:
            xlabel = kwargs["xlabel"]

        if "ylabel" not in kwargs:
            ylabel = ""
        else:
            ylabel = kwargs["ylabel"]

        histogram = plt.hist(
            sample=y_data,
            bins=num_bins,
            axes_options={
                "count": {
                    "label": ylabel
                },
                "sample": {
                    "label": xlabel
                }
            },
        )

        if "colors" in kwargs:
            histogram.colors = kwargs["colors"]
        if "stroke" in kwargs:
            histogram.stroke = kwargs["stroke"]
        else:
            histogram.stroke = "#ffffff00"
        if "stroke_width" in kwargs:
            histogram.stroke_width = kwargs["stroke_width"]
        else:
            histogram.stroke_width = 0

        if ("xlabel" in kwargs) and ("ylabel" in kwargs):
            histogram.tooltip = Tooltip(
                fields=["midpoint", "count"],
                labels=[kwargs["xlabel"], kwargs["ylabel"]],
            )
        else:
            histogram.tooltip = Tooltip(fields=["midpoint", "count"])
        plt.show()

    except Exception as e:
        raise Exception(e)
Exemple #4
0
import numpy as np
import bqplot.pyplot as plt

size = 100

plt.figure(title='Scatter plot with colors')
plt.scatter(np.random.randn(size), np.random.randn(size), color=np.random.randn(size))
plt.show()
Exemple #5
0
def feature_byFeature(features, xProperty, yProperties, **kwargs):
    """Generates a Chart from a set of features. Plots the value of one or more properties for each feature.
    Reference: https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturebyfeature

    Args:
        features (ee.FeatureCollection): The feature collection to generate a chart from.
        xProperty (str): Features labeled by xProperty.
        yProperties (list): Values of yProperties.

    Raises:
        Exception: Errors when creating the chart.
    """

    try:

        df = ee_to_df(features)
        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = df[yProperties].to_numpy().min()
            max_value = df[yProperties].to_numpy().max()
            max_value = max_value + 0.2 * (max_value - min_value)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]
        if "legend_location" not in kwargs:
            legend_location = "top-left"
        else:
            legend_location = kwargs["legend_location"]

        x_data = list(df[xProperty])
        y_data = df[yProperties].values.T.tolist()

        plt.bar(x_data, y_data)
        fig = plt.figure(
            title=title,
            legend_location=legend_location,
        )

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        if "labels" in kwargs:
            labels = kwargs["labels"]
        else:
            labels = yProperties

        if "display_legend" not in kwargs:
            display_legend = True
        else:
            display_legend = kwargs["display_legend"]

        bar_chart = plt.bar(x_data,
                            y_data,
                            labels=labels,
                            display_legend=display_legend)

        bar_chart.type = "grouped"

        if "colors" in kwargs:
            bar_chart.colors = kwargs["colors"]

        if "xlabel" in kwargs:
            plt.xlabel(kwargs["xlabel"])
        if "ylabel" in kwargs:
            plt.ylabel(kwargs["ylabel"])
        plt.ylim(min_value, max_value)

        if "xlabel" in kwargs and ("ylabel" in kwargs):
            bar_chart.tooltip = Tooltip(
                fields=["x", "y"], labels=[kwargs["xlabel"], kwargs["ylabel"]])
        else:
            bar_chart.tooltip = Tooltip(fields=["x", "y"])

        plt.show()

    except Exception as e:
        raise Exception(e)
Exemple #6
0
    def create_output_widgets(self):
        # create the output widgets
        self.tasks_done_bar = widgets.IntProgress(
            value=0,
            min=0,
            max=self.ending_task - self.starting_task,
            description='Percent of tasks complete:',
            style={'description_width': 'initial'},
            orientation='horizontal')
        self.tasks_idling = widgets.IntProgress(
            value=0,
            min=0,
            max=self.max_workers,
            description='Percent of workers idle',
            style={'description_width': 'initial'},
            orientation='horizontal')
        self.workers_connected = widgets.IntProgress(
            value=0,
            min=0,
            max=self.max_workers,
            description='Percent of max workers connected',
            style={'description_width': 'initial'},
            orientation='horizontal')
        self.status_message = widgets.Text(
            value='Initializing workers',
            description='Workqueue Status',
            disabled=True,
            style={'description_width': 'initial'},
            orientation='horizontal')
        self.worker_time = widgets.Text(
            description='Time spent by workers (Seconds)',
            disabled=True,
            style={'description_width': 'initial'},
            orientation='horizontal')
        self.tasks_per_second = widgets.FloatText(
            value=0,
            description='Average tasks complete per second',
            style={'description_width': 'initial'},
            disabled=True)
        self.task_output_storage = []  # clear output from previous runs
        # display output
        display(
            widgets.HBox(
                [self.status_message, self.tasks_per_second,
                 self.worker_time]))
        display(
            widgets.HBox([
                self.tasks_done_bar, self.workers_connected, self.tasks_idling
            ]))
        # initialize real time task display output
        for i in range(self.starting_task,
                       self.ending_task + self.max_workers + 10):
            self.task_output_storage.append(
                widgets.ToggleButton(
                    value=False,
                    description=str(i - 2),
                    disabled=False,
                    button_style=
                    '',  # 'success', 'info', 'warning', 'danger' or ''
                    layout=widgets.Layout(width='20%', height='20px')))
        horizontal_boxes = 15
        vertical_boxes = (self.ending_task -
                          self.starting_task) // horizontal_boxes + 1
        vertical_temp = []
        # actually place the real time display output on screen
        for j in range(vertical_boxes):
            horizontal_temp = []
            for i in range(horizontal_boxes):
                if (i + j * horizontal_boxes + 2) > (self.ending_task):
                    break
                horizontal_temp.append(
                    self.task_output_storage[i + j * horizontal_boxes + 2])
            vertical_temp.append(widgets.HBox(horizontal_temp))
        display(widgets.VBox(vertical_temp))

        self.starting_time = time.perf_counter()  # reset starting time

        # below are just properties of the worker time pie chart
        fig = plt.figure(title="Work Queue Time Distribution (Milliseconds)")
        self.pie = plt.pie(sizes=[0, 0, 0],
                           labels=[
                               'Work Queue internal', 'Waiting for workers',
                               'Application'
                           ],
                           display_values=True,
                           values_format=".1f",
                           display_labels='outside')
        self.pie.stroke = "black"
        self.pie.colors = ["tomato", "lawngreen", "gray"]

        self.pie.radius = 150
        self.pie.inner_radius = 60

        self.pie.label_color = 'orangered'
        self.pie.font_size = '20px'
        self.pie.font_weight = 'bold'
        plt.show()
Exemple #7
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'}
import numpy as np
import bqplot.pyplot as plt

size = 100

plt.figure(title="Scatter plot with colors")
plt.scatter(np.random.randn(size), np.random.randn(size), color=np.random.randn(size))
plt.show()
Exemple #9
0
b = b * 30

x_sc = bqplot.LinearScale()
y_sc = bqplot.LinearScale()

ax_x = bqplot.Axis(scale=x_sc, label="X-value")
ax_y = bqplot.Axis(scale=y_sc, label="Y-value", orientation='vertical')

scatters1 = bqplot.Scatter(x=a[:, 0],
                           y=a[:, 1],
                           scales={
                               'x': x_sc,
                               'y': y_sc
                           },
                           default_size=5,
                           colors=["navy"],
                           sizes=[10])
scatters2 = bqplot.Scatter(x=b[:, 0],
                           y=b[:, 1],
                           scales={
                               'x': x_sc,
                               'y': y_sc
                           },
                           default_size=2,
                           colors=['orange'],
                           sizes=[5])

fig = bqplot.Figure(marks=[scatters1, scatters2], axes=[ax_x, ax_y])

plt.show(fig)
Exemple #10
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.")