Skip to content

Commit

Permalink
arrayglyph/replace array by masked array (#78)
Browse files Browse the repository at this point in the history
ArrayGlyph
^^^^^^^^^^
* the `ArrayGlyph` constructor uses a masked array instead of a numpy array.
  • Loading branch information
MAfarrag authored Jul 23, 2024
1 parent 7ce9159 commit 469b17b
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,4 @@ repos:
name: doctest
entry: pytest --doctest-modules
language: system
files: \.py$
files: cleopatra\.py$
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pip install git+https://github.com/Serapieum-of-alex/cleopatra
## pip
to install the last release, you can easily use pip
```
pip install cleopatra==0.4.4
pip install cleopatra==0.5.1
```

Quick start
Expand Down
46 changes: 24 additions & 22 deletions cleopatra/array_glyph.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from matplotlib.figure import Figure
from matplotlib.axes import Axes
import numpy as np
import numpy.ma as ma
from hpc.indexing import get_indices2

# from matplotlib import gridspec
Expand Down Expand Up @@ -67,7 +68,7 @@ def __init__(
cutoff: List = None,
ax: Axes = None,
fig: Figure = None,
percentile: int = 1,
percentile: int = None,
**kwargs,
):
"""Array.
Expand All @@ -80,8 +81,9 @@ def __init__(
value used to fill cells out of the domain.
extent: List, Default is None.
[xmin, ymin, xmax, ymax].
rgb: List, Default is [3,2,1]
the indices of the red, green, and blue bands in the given array.
rgb: List
the indices of the red, green, and blue bands in the given array. the `rgb` parameter can be a list of
three values, or a list of four values if the alpha band is also included.
surface_reflectance: int, Default is 10000.
surface reflectance value of the sentinel data.
cutoff: List, Default is None.
Expand Down Expand Up @@ -121,16 +123,16 @@ def __init__(
# first replace the no_data_value by nan
# convert the array to float32 to be able to replace the no data value with nan
if exclude_value is not np.nan:
array = array.astype(np.float32)
if len(exclude_value) > 1:
mask = np.logical_or(
np.isclose(array, exclude_value[0], rtol=0.001),
np.isclose(array, exclude_value[1], rtol=0.001),
)
else:
mask = np.isclose(array, exclude_value[0], rtol=0.0000001)

array[mask] = np.nan
array = ma.array(array, mask=mask, dtype=array.dtype)
else:
array = ma.array(array)

# convert the extent from [xmin, ymin, xmax, ymax] to [xmin, xmax, ymin, ymax] as required by matplotlib.
if extent is not None:
Expand Down Expand Up @@ -170,11 +172,9 @@ def __init__(
self.ticks_spacing = (self._vmax - self._vmin) / 10
shape = array.shape
if len(shape) == 3:
no_elem = np.size(array[0, :, :]) - np.count_nonzero(
(array[0, np.isnan(array[0, :, :])])
)
no_elem = array[0, :, :].count()
else:
no_elem = np.size(array[:, :]) - np.count_nonzero((array[np.isnan(array)]))
no_elem = array.count()

self.no_elem = no_elem
if fig is None:
Expand All @@ -188,7 +188,7 @@ def prepare_array(
rgb: List[int] = None,
surface_reflectance: int = None,
cutoff: List = None,
percentile: int = 1,
percentile: int = None,
) -> np.ndarray:
"""Prepare Array.
Expand All @@ -208,16 +208,17 @@ def prepare_array(
Returns
-------
np.ndarray:
np.ndarray: np.float32
the rgb 3d array is converted into 2d array to be plotted using the plt.imshow function.
a float32 array normalized between 0 and 1 using the percentile values.
"""
# take the rgb arrays and reorder them to have the red-green-blue, if the order is not given, assume the
# order as sentinel data. [3, 2, 1]
array = array[rgb].transpose(1, 2, 0)

if surface_reflectance is None:
if percentile is not None:
array = self.scale_percentile(array, percentile=percentile)
else:
elif surface_reflectance is not None:
array = self._prepare_sentinel_rgb(
array,
rgb=rgb,
Expand Down Expand Up @@ -273,7 +274,7 @@ def scale_percentile(arr: np.ndarray, percentile: int = 1) -> np.ndarray:
Returns
-------
np.ndarray
np.ndarray: float32
The scaled array, normalized between 0 and 1. using the percentile values.
"""
rows, columns, bands = arr.shape
Expand Down Expand Up @@ -440,6 +441,7 @@ def _plot_im_get_cbar_kw(
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
im = ax.matshow(arr, cmap=cmap, norm=norm, extent=self.extent)
elif color_scale.lower() == "midpoint":
arr = arr.filled(np.nan)
im = ax.matshow(
arr,
cmap=cmap,
Expand Down Expand Up @@ -484,7 +486,7 @@ def _plot_text(
add_text = lambda elem: ax.text(
elem[1],
elem[0],
round(arr[elem[0], elem[1]], 2),
np.round(arr[elem[0], elem[1]], 2),
ha="center",
va="center",
color="w",
Expand Down Expand Up @@ -574,12 +576,12 @@ def plot(
**kwargs: [dict]
title: [str], optional
title of the plot. The default is 'Total Discharge'.
title_size: [integer], optional
title size. The default is 15.
cbar_orientation: [string], optional
orientation of the color bar horizontal/vertical. The default is 'vertical'.
cbar_label_rotation: [number], optional
rotation of the color bar label. The default is -90.
title_size: [integer], optional, default is 15.
title size.
cbar_orientation: [string], optional, default is 'vertical'
orientation of the color bar horizontal/vertical.
cbar_label_rotation: [number], optional, default is -90.
rotation of the color bar label.
cbar_label_location: str, optional, default is 'bottom'.
location of the color bar title 'top', 'bottom', 'center', 'baseline', 'center_baseline'.
cbar_length: float, optional
Expand Down
9 changes: 7 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import os
import sys

from importlib.metadata import version, PackageNotFoundError

# for the auto documentation to work
# If extensions (or modules to document with autodoc) are in another directory,
Expand All @@ -21,8 +21,13 @@
project = "cleopatra"
copyright = "2024, Mostafa Farrag"
author = "Mostafa Farrag"
release = "0.4.4"
# Read the version from the package
try:
release = version("cleopatra")
except PackageNotFoundError:
release = "unknown"

version = release
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

setup(
name="cleopatra",
version="0.5.0",
version="0.5.1",
description="visualization package",
author="Mostafa Farrag",
author_email="[email protected]",
Expand Down
3 changes: 2 additions & 1 deletion tests/test_plot_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class TestCreateArray:
def test_create_instance(self, arr: np.ndarray, no_data_value: float):
array = ArrayGlyph(arr, exclude_value=[no_data_value])
assert isinstance(array.arr, np.ndarray)
assert np.isnan(array.arr[0, 0])
# check if the first element is masked
assert array.arr.mask[0, 0]
assert array.no_elem == 89
assert array.vmin == 0
assert array.vmax == 88
Expand Down

0 comments on commit 469b17b

Please sign in to comment.