Esempio n. 1
0
def plot_predicted_probabilities(predictions, groundtruth, n_classes, uncertainty):
    """ plot predictions with ground truth
    
    arguments
    ---------
        predictions: numpy nd.array
            probability maps of classes of patches
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
        groundtruth: numpy nd.array
            one-hot lables of patches
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
        nclasses: int
            number of prediction classes
        uncertainty: float between 0 and 1
            if uncertainty is higher than this number, class 'unsure' is assigned
            
    
    output
    ------
        figure with predictionsmaps plotted in first n rows and ground truth in last row. 
        The columns represent differnet patches.
    """

    #colors_extra = ['linen', 'lightgreen', 'limegreen', 'darkgreen', 'yellow', 'black']
    colors_extra = np.array([(194/256,230/256,153/256),(120/256,198/256,121/256),
    (49/256,163/256,84/256),(0/256,76/256,38/256),(229/256,224/256,204/256),(0,0,0)])
    cmap_extra = ListedColormap(colors_extra)
    
    n_patches = len(predictions)
    rows = 7
    
    # prepare
    fig, ax = plt.subplots(rows,n_patches)
    
    for i in range(n_patches):
    
        im = predictions[i]
        gt = groundtruth[i]
        
        # prepare prediction plot
        plt_im  = np.zeros_like(im, dtype=np.uint8)
        plt_im = np.argmax(im, axis=2)
        plt_im[np.max(im, axis=2)<(1-uncertainty)] = 5

        
        # plot probability maps
        for j in range(n_classes):
            ax[j,i].imshow(im[:,:,j], vmin=0, vmax=1)
        
        # prepare gt plot
        plt_gt  = np.zeros_like(gt, dtype=np.uint8)
        plt_gt = np.argmax(gt, axis=2)
        
        # plot prediction 
        im = ax[5,i].imshow(plt_im, cmap=cmap_extra, vmin=0, vmax=5) 
        
        # plot gt 
        grtr = ax[6,i].imshow(plt_gt, cmap=cmap, vmin=0, vmax=4) 
    
    ep.draw_legend(im,titles=["tara0", "tara20", "tara50", "forest","non-cultivable","not sure"],classes=[0, 1, 2, 3,4,5])
Esempio n. 2
0
def NDVI(bands, year):
	"""Normalized Difference Vegetation Index (NDVI)"""

	#ndvi = es.normalized_diff(band4, band3)      # (band4-band3)/(band4+band3)
	ndvi = es.normalized_diff(bands[3], bands[2]) # (band4-band3)/(band4+band3)

	titles = ['Normalized Difference Vegetation Index (NDVI) Year: %s' %year]

	# Turn off bytescale scaling due to float values for NDVI
	ep.plot_bands(ndvi, cmap="RdYlGn", cols=1, title=titles, vmin=-1, vmax=1)

	# Create classes and apply to NDVI results
	ndvi_class_bins    = [-np.inf, 0, 0.25, 0.5, 0.75, np.inf]
	ndvi_landsat_class = np.digitize(ndvi, ndvi_class_bins)

	# Define color map and class names
	ndvi_colors = ListedColormap(['gray', 'y', 'yellowgreen', 'g', 'darkgreen'])
	ndvi_names = ['0.00 No Vegetation','0.25 Bare Area','0.50 Low Vegetation','0.75 Moderate Vegetation','1.00 High Vegetation']

	# Get list of classes
	classes = np.unique(ndvi_landsat_class).tolist()

	fig, ax = plt.subplots(figsize=(8, 8))
	im      = ax.imshow(ndvi_landsat_class, cmap=ndvi_colors)

	ep.draw_legend(im_ax=im, classes=classes, titles=ndvi_names)
	ax.set_title('Normalized Difference Vegetation Index (NDVI) Classes. \nYear: %s' %yr,fontsize=14)
	ax.set_axis_off(); plt.tight_layout()
	plt.show()
def test_non_ax_obj():
    """Draw_legend fun should raise AttributeError if provided with a
    non mpl axis object"""

    with pytest.raises(
            AttributeError,
            match="The legend function requires a matplotlib axis object",
    ):
        ep.draw_legend(im_ax=list())
Esempio n. 4
0
def plot_predicted_patches(predictions, groundtruth, patch=None):
    """ plot predicted patches with ground truth
    
    arguments
    ---------
        predictions: numpy nd.array
            probability maps of classes of patches
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
        groundtruth: numpy nd.array
            one-hot lables of patches
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
        patch: numpy.ndarray
            image of patch
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
    
    output
    ------
        figure with n predictions plotted in first row and ground truth in second row.
        if patch is specified the third row contains RGB image
    """

    n_patches = len(predictions)
    cols = 2
    if np.any(patch != None):
        cols = 3
    
    
    # prepare
    fig, ax = plt.subplots(n_patches,cols, figsize=(15,15))
    
    for i in range(n_patches):
    
        im = predictions[i]
        gt = groundtruth[i]
        
        # prepare prediction plot
        plt_im  = np.zeros_like(im, dtype=np.uint8)
        plt_im = np.argmax(im, axis=2)
        
        # prepare gt plot
        plt_gt  = np.zeros_like(gt, dtype=np.uint8)
        plt_gt = np.argmax(gt, axis=2)
    
        # plot training image
        ax[i,0].imshow(plt_im, cmap=cmap, vmin=0, vmax=4)
        
        # plot gt 
        grtr = ax[i,1].imshow(plt_gt, cmap=cmap, vmin=0, vmax=4) 
        
        # plot RGB
        if np.any(patch != None):
            plt_im = patch[i][:, :, [0,1,2]].astype(np.float64)
            ax[i,2].imshow(plt_im)
    
    ep.draw_legend(grtr,titles=["tara0", "tara20", "tara50", "woods","no coltivable"],classes=[0, 1, 2, 3,4])
def test_listedcmap_ncol_equals_nclasses(vals_missing_plot_list_cmap):
    """If a 5 color listed cmap is provided and 6 classes are specified, return value error"""

    n_classes = 5
    im_ax, arr = vals_missing_plot_list_cmap

    with pytest.raises(
            ValueError,
            match="There are more classes than colors in your cmap"):
        ep.draw_legend(im_ax, classes=np.arange(0, n_classes + 1))
    plt.close()
Esempio n. 6
0
def test_subplots(binned_array):
    """Test to ensure that a plot with subplots still has a legend."""

    bins, arr_class = binned_array

    f, (ax1, ax2) = plt.subplots(2, 1)
    im_ax = ax1.imshow(arr_class)
    ep.draw_legend(im_ax)

    im_ax2 = ax2.imshow(arr_class)
    ep.draw_legend(im_ax2)
    plt.close(f)
Esempio n. 7
0
def plot_random_patches(patches_path, n_patches, classes, class_names):
    """ plot random patches with ground truth
    
    arguments
    ---------
        patches_path: string
            path to folder containing the patches 
        n_patches: int
            number of random patches to plot
        classes: list
            list of predicted classes
        class_names: list
            
    output
    ------
        figure with n_patches plotted in first row and ground truth in second row.
    """
    
    images_path = patches_path + 'images/'
    labels_path = patches_path + 'labels/'
    
    rows = 2
    cols = n_patches    
    
    
    # get path images list
    im_list = list_files(images_path, '.npy')
    gt_list = list_files(labels_path, '.npy')
    
    # prepare
    index = np.array([0,1,2])
    fig, ax = plt.subplots(rows,cols)
    
    for i in range(n_patches):
        idx=np.random.randint(len(im_list))
        im = np.load(images_path + im_list[idx])
        gt = np.load(labels_path + gt_list[idx])
        
        # prepare RGB plot
        plt_im = im[:, :, index].astype(np.float64)
        
        # prepare gt plot
        plt_gt  = np.zeros_like(gt, dtype=np.uint8)
        plt_gt = np.argmax(gt, axis=2)
    
        # plot training image
        image = ax[0,i].imshow(plt_im)
        
        # plot gt 
        grtr = ax[1,i].imshow(plt_gt, cmap=cmap, vmin=0, vmax=4) #colors not right
    
    ep.draw_legend(grtr,titles=class_names,classes=classes)
Esempio n. 8
0
    def plot_categorical_w_window(self, output_file, labels, cmap, xy, width, height, box=True):
        """Creates a figure of a categorical raster with a zoomed window

        :param output_file: path, file path of the figure
        :param labels: list of strings, labels (i.e., titles)for the categories
        :param cmap: string, colormap to plot the raster
        :param xy: tuple (x,y), origin of the zoomed window, the upper left corner
        :param width: integer, width (number of cells) of the zoomed window
        :param height: integer, height (number of cells) of the zoomed window

        :returns: saves the figure of the raster
        """
        raster_np = read_raster(self.path)
        print('Classes identified in the raster: ', np.unique(raster_np))
        # cmap = matplotlib.colors.ListedColormap(list_colors)
        fig, ax = plt.subplots(1, 2)

        ax[0].imshow(raster_np, cmap=cmap)
        rectangle = patches.Rectangle(xy, width, height, fill=False)
        ax[0].add_patch(rectangle)
        plt.setp(ax, xticks=[], yticks=[])

        #  Plot Patch
        box_np = raster_np[xy[1]: xy[1] + height, xy[0]: xy[0] + width]
        im = ax[1].imshow(box_np, cmap=cmap)
        cbar = ep.draw_legend(im, titles=labels)
        # cbar.ax[].tick_params(labelsize=20)

        if not box:
            ax.axis('off')
        fig.savefig(output_file, dpi=700, bbox_inches='tight')
def test_listed_cmap(arr_plot_list_cmap):
    """Test that the the legend generates properly when provided with a ListedColormap"""

    im_ax, arr = arr_plot_list_cmap

    leg = ep.draw_legend(im_ax)
    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == len(np.unique(arr))
    plt.close()
Esempio n. 10
0
def test_num_titles_classes(binned_array_3bins):
    """Test to ensure the the number of "handles" or classes provided for each
    legend items matches the number of classes being used to build the legend.
    This case should return a ValueError if these items are different"""
    bins, im_arr_bin = binned_array_3bins
    im_arr_bin[im_arr_bin == 2] = 3

    fig, ax = plt.subplots(figsize=(5, 5))
    im_ax = ax.imshow(im_arr_bin, cmap="Blues")

    with pytest.raises(ValueError):
        ep.draw_legend(im_ax=im_ax,
                       classes=[1, 2],
                       titles=["small", "medium", "large"])

    with pytest.raises(ValueError):
        ep.draw_legend(im_ax=im_ax,
                       classes=[1, 2, 3],
                       titles=["small", "large"])
Esempio n. 11
0
def plot_patches(patch, gt, n_patches):
    """ plot patches with ground truth
    
    arguments
    ---------
        patch: numpy.ndarray
            image of patch
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
        gt: numpy.ndarray
            one-hot lables of patches
            shape = (n_patches, patch_size_padded, patch_size_padded, n_classes)
        n_patches: int
            number of random patches to plot
            
    output
    ------
        figure with n_patches plotted in first row and ground truth in second row.
    """
    
    rows = 2
    cols = n_patches    
    
    # prepare
    index = np.array([0,1,2])
    fig, ax = plt.subplots(rows,cols)
    
    for i in range(n_patches):
        
        # prepare RGB plot
        plt_im = patch[i][:, :, index].astype(np.float64)
        
        # prepare gt plot
        plt_gt  = np.zeros_like(gt[i], dtype=np.uint8)
        plt_gt = np.argmax(gt[i], axis=2)
    
        # plot training image
        image = ax[0,i].imshow(plt_im)
        
        # plot gt 
        grtr = ax[1,i].imshow(plt_gt, cmap=cmap, vmin=0, vmax=4)
    
    ep.draw_legend(grtr,titles=["tara0", "tara20", "tara50", "forest","non-cultivable"],classes=[0, 1, 2, 3,4])
def test_noncont_listed_cmap(vals_missing_plot_list_cmap):
    """An arr with 3 vals (missing the 1, and 5) which requires normalization
     produces creates a legend with 3 handles."""

    im_ax, arr = vals_missing_plot_list_cmap

    leg = ep.draw_legend(im_ax)

    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == len(np.unique(arr))
    plt.close()
def test_classes_provided_as_array(arr_plot_list_cmap):
    """Test that draw_legend works when classes are provided as an arr (not a list)."""

    im_ax, arr = arr_plot_list_cmap
    n_classes = 5

    leg = ep.draw_legend(im_ax, classes=np.arange(n_classes))

    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == n_classes
    plt.close()
def test_neg_vals():
    """Test that the legend plots when positive and negative values are provided"""

    arr = np.array([[-1, 0, 1], [1, 0, -1]])
    f, ax = plt.subplots()
    im_ax = ax.imshow(arr)

    leg_neg = ep.draw_legend(im_ax)
    legend_cols = [i.get_facecolor() for i in leg_neg.get_patches()]
    assert len(legend_cols) == len(np.unique(arr))
    plt.close(f)
Esempio n. 15
0
def test_neg_vals(binned_array):
    """Test that the things plot when positive and negative vales
    are provided"""
    bins, arr_class = binned_array

    f, ax = plt.subplots()
    im_ax = ax.imshow(arr_class)
    leg_neg = ep.draw_legend(im_ax)
    legend_cols = [i.get_facecolor() for i in leg_neg.get_patches()]
    assert len(legend_cols) == len(bins) - 1
    plt.close(f)
Esempio n. 16
0
    def plot_categorical_raster(self, output_file, labels, cmap, box=True):
        """Creates a figure of a categorical raster

        :param output_file: path, file path of the figure
        :param labels: list of strings, labels (i.e., titles)for the categories
        :param cmap: string, colormap to plot the raster
        :param box: boolean, if False it sets off the frame of the picture

        :returns: saves the figure of the raster
        """
        raster_np = read_raster(self.path)
        print('Classes identified in the raster: ', np.unique(raster_np))
        # cmap = matplotlib.colors.ListedColormap(list_colors)
        fig, ax = plt.subplots()
        im = ax.imshow(raster_np, cmap=cmap)
        ep.draw_legend(im, titles=labels)
        ax.set_axis_off()
        # plt.show()
        if not box:
            ax.axis('off')
        fig.savefig(output_file, dpi=200, bbox_inches='tight')
def test_num_titles_classes(arr_plot_blues):
    """Test that the number of classes equals the number of legend titles"""

    im_ax, _ = arr_plot_blues

    with pytest.raises(
            ValueError,
            match="The number of classes should equal the number of titles",
    ):
        ep.draw_legend(im_ax=im_ax,
                       classes=[1, 2],
                       titles=["small", "medium", "large"])

    with pytest.raises(
            ValueError,
            match="The number of classes should equal the number of titles",
    ):
        ep.draw_legend(im_ax=im_ax,
                       classes=[1, 2, 3],
                       titles=["small", "large"])
    plt.close()
def test_cont_cmap_3_classes(vals_missing_plot_cont_cmap):
    """Test legend for a listed cmap where
    the user wants all classes to be drawn in the legend. IE the classified
    image has classes 2,3,4 and the user wants classes 1-5 to appear """

    im_ax, arr = vals_missing_plot_cont_cmap

    class_list = list(range(5))
    leg = ep.draw_legend(im_ax, classes=class_list)
    legend_cols = [i.get_facecolor() for i in leg.get_patches()]

    assert len(legend_cols) == len(class_list)
    plt.close()
def test_stock_legend_titles(arr_plot_blues):
    """Test that the correct number of default titles plot"""

    im_ax, im_arr_bin = arr_plot_blues

    # Default legend title values
    def_titles = ["Category {}".format(i) for i in np.unique(im_arr_bin)]

    the_legend = ep.draw_legend(im_ax=im_ax)
    # Legend handle titles should equal unique values in ax array
    assert len(the_legend.get_texts()) == len(np.unique(
        im_ax.get_array().data))
    assert def_titles == [text.get_text() for text in the_legend.get_texts()]
    plt.close()
def test_colors(arr_plot_blues):
    """Test that the correct colors appear in the patches of the legend"""

    im_ax, _ = arr_plot_blues
    the_legend = ep.draw_legend(im_ax=im_ax)

    legend_cols = [i.get_facecolor() for i in the_legend.get_patches()]
    # Get the array and cmap from axis object
    cmap_name = im_ax.axes.get_images()[0].get_cmap().name
    unique_vals = np.unique(im_ax.get_array().data)
    image_colors = ep.make_col_list(unique_vals, cmap=cmap_name)

    assert image_colors == legend_cols
    plt.close()
def test_custom_legend_titles(arr_plot_blues):
    """Test that the correct number of custom legend titles plot"""

    im_ax, _ = arr_plot_blues

    custom_titles = ["one", "two", "three"]
    the_legend = ep.draw_legend(im_ax=im_ax, titles=custom_titles)

    assert len(the_legend.get_texts()) == len(np.unique(
        im_ax.get_array().data))
    assert custom_titles == [
        text.get_text() for text in the_legend.get_texts()
    ]
    plt.close()
Esempio n. 22
0
def test_custom_legend_titles(binned_array_3bins):
    """Test that the correct number of and text for custom legend titles
    plot when titles parameter = None"""
    bins, im_arr_bin = binned_array_3bins

    f, ax = plt.subplots()
    imp2 = ax.imshow(im_arr_bin, cmap="Blues")
    custom_titles = ["one", "two", "three"]

    the_legend = ep.draw_legend(im_ax=imp2, titles=custom_titles)
    assert len(the_legend.get_texts()) == len(np.unique(imp2.get_array().data))
    assert custom_titles == [
        text.get_text() for text in the_legend.get_texts()
    ]
    plt.close(f)
Esempio n. 23
0
def test_noncont_listed_cmap_3_classes(binned_array, listed_cmap):
    """Test legend for a non continuous listed cmap where
    the user wants all classes to be drawn in the legend. IE the classified
    image has classes 2,3,4 and the user wants classes 1-5 to appear """

    cmap, norm = listed_cmap
    bins, arr_class = binned_array

    f, ax = plt.subplots(figsize=(5, 5))
    im = ax.imshow(arr_class, cmap=cmap, norm=norm)
    leg = ep.draw_legend(im, classes=[1, 2, 3, 4, 5])

    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == len([1, 2, 3, 4, 5])
    plt.close(f)
Esempio n. 24
0
def test_listed_cmap(binned_array):
    """Test that the the legend generates properly when provided with a Listed
     colormap"""

    bins, arr_class = binned_array

    # TODO make the list of colors a fixture for reuse
    cmap_list = ListedColormap(
        ["white", "tan", "purple", "springgreen", "darkgreen"])
    f, ax = plt.subplots()
    im_plt = ax.imshow(arr_class, cmap=cmap_list)
    leg = ep.draw_legend(im_plt)
    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == len(bins) - 1
    plt.close(f)
Esempio n. 25
0
def test_masked_vals():
    """Test to ensure that a masked array plots properly"""
    im_arr = np.random.uniform(-2, 1, (15, 15))
    bins = [-0.8, -0.2, 0.2, 0.8, np.Inf]
    im_arr_bin = np.digitize(im_arr, bins)
    arr_bin_ma = np.ma.masked_equal(im_arr_bin, 0)
    unmasked_vals = [
        val for val in np.unique(arr_bin_ma) if val is not np.ma.core.masked
    ]

    f, ax = plt.subplots()
    im_ax = ax.imshow(arr_bin_ma)
    leg = ep.draw_legend(im_ax)
    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == len(unmasked_vals)
    plt.close(f)
Esempio n. 26
0
def test_colors(binned_array_3bins):
    """Test that the correct colors appear in the patches of the legend"""

    bins, im_arr_bin = binned_array_3bins

    f, ax = plt.subplots()
    im = ax.imshow(im_arr_bin, cmap="Blues")
    the_legend = ep.draw_legend(im_ax=im)
    # NOTE: Do I know for sure things are rendering in the right order?
    legend_cols = [i.get_facecolor() for i in the_legend.get_patches()]
    # Get the array and cmap from axis object
    cmap_name = im.axes.get_images()[0].get_cmap().name
    unique_vals = np.unique(im.get_array().data)
    image_colors = ep.make_col_list(unique_vals, cmap=cmap_name)

    assert image_colors == legend_cols
Esempio n. 27
0
def test_stock_legend_titles(binned_array_3bins):
    """Test that the correct number of generic titles plot when titles
    parameter = None"""

    bins, im_arr_bin = binned_array_3bins

    f, ax = plt.subplots()
    imp2 = ax.imshow(im_arr_bin, cmap="Blues")

    # Default legend title values should be
    def_titles = ["Category {}".format(i) for i in np.unique(im_arr_bin)]

    the_legend = ep.draw_legend(im_ax=imp2)
    # Legend handle titles should equal unique values in ax array
    assert len(the_legend.get_texts()) == len(np.unique(imp2.get_array().data))
    assert def_titles == [text.get_text() for text in the_legend.get_texts()]
    plt.close(f)
Esempio n. 28
0
def test_noncont_listed_cmap(binned_array, listed_cmap):
    """Test that an arr with 3 classes (missing the 1, and 5) which
     would need to be normalized, only creates a legend with x handles
     by default"""

    cmap, norm = listed_cmap
    bins, arr_class = binned_array

    arr_class[arr_class == 1] = 2
    arr_class[arr_class == 5] = 4

    f, ax = plt.subplots(figsize=(5, 5))
    im = ax.imshow(arr_class, cmap=cmap, norm=norm)
    leg = ep.draw_legend(im)

    legend_cols = [i.get_facecolor() for i in leg.get_patches()]
    assert len(legend_cols) == len(np.unique(arr_class))
    plt.close(f)
Esempio n. 29
0
nbr_cmap = ListedColormap(nbr_colors)

# Define class names
ndvi_cat_names = [
    "No Vegetation",
    "Bare Area",
    "Low Vegetation",
    "Moderate Vegetation",
    "High Vegetation",
]

# Get list of classes
classes = np.unique(ndvi_landsat_class)
classes = classes.tolist()
# The mask returns a value of none in the classes. remove that
classes = classes[0:5]

# Plot your data
fig, ax = plt.subplots(figsize=(12, 12))
im = ax.imshow(ndvi_landsat_class, cmap=nbr_cmap)

ep.draw_legend(im_ax=im, classes=classes, titles=ndvi_cat_names)
ax.set_title(
    "Landsat 8 - Normalized Difference Vegetation Index (NDVI) Classes",
    fontsize=14,
)
ax.set_axis_off()

# Auto adjust subplot to fit figure size
plt.tight_layout()
# Create a colormap with 11 colors
cmap = plt.cm.get_cmap('tab20b', 11)
# Get a list of unique values in the qa layer
vals = np.unique(landsat_qa).tolist()
bins = [0] + vals
# Normalize the colormap
bounds = [((a + b) / 2) for a, b in zip(bins[:-1], bins[1::1])] + \
    [(bins[-1] - bins[-2]) + bins[-1]]
norm = colors.BoundaryNorm(bounds, cmap.N)

# Plot the data
fig, ax = plt.subplots(figsize=(12, 8))

im = ax.imshow(landsat_qa, cmap=cmap, norm=norm)

ep.draw_legend(im, classes=vals, cmap=cmap, titles=vals)

ax.set_title("Landsat Collection Quality Assessment Layer")
ax.set_axis_off()
plt.show()
# -

# In the image above, you can see the cloud and the shadow that is obstructing our landsat image.
# Unfortunately for you, this cloud covers a part of your analysis area in the Cold Springs
# Fire location. There are a few ways to handle this issue. We will look at one:
# simply masking out or removing the cloud for your analysis, first.
#
# To remove all pixels that are cloud and cloud shadow covered we need to first
# determine what each value in our qa raster represents. The table below is from the USGS landsat website.
# It describes what all of the values in the pixel_qa layer represent.
#