Skip to content

Commit

Permalink
fix: make sure every plot can be called without ax paramaters (#365)
Browse files Browse the repository at this point in the history
  • Loading branch information
12rambau authored Oct 28, 2024
2 parents 819dbda + eb069b9 commit 1273b71
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 189 deletions.
Binary file added docs/_static/usage/plot/index/histogram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/_static/usage/plot/index/hydroshed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@
autoapi_keep_files = False

# -- Options for intersphinx output --------------------------------------------
intersphinx_mapping = {}
intersphinx_mapping = {
"matplotlib": ("https://matplotlib.org/stable/", None),
}

# -- options for the autolabel extension ---------------------------------------
autosectionlabel_prefix_document = True
Expand Down
91 changes: 89 additions & 2 deletions docs/usage/plot/index.rst
Original file line number Diff line number Diff line change
@@ -1,12 +1,99 @@
Plotting
========

We embed some plotting capabilities in the library to help you visualize your data.
We embed some plotting capabilities in the library to help you visualize your data. For simplicity we decided to map all the plotting function to the :doc:`matplotlib <matplotlib:index>` library as it's the most used static plotting library in the Python ecosystem.

.. toctree::
:hidden:
:maxdepth: 1

plot-featurecollection
plot-image
plot-imagecollection
map-image
map-featurecollection
map-featurecollection

.. grid:: 1 2 3 3

.. grid-item::

.. card:: :icon:`fa-solid fa-chart-simple` FeatureCollection
:link: plot-featurecollection.html

.. grid-item::

.. card:: :icon:`fa-solid fa-chart-simple` Image
:link: plot-image.html

.. grid-item::

.. card:: :icon:`fa-solid fa-chart-simple` ImageCollection
:link: plot-imagecollection.html

.. grid-item::

.. card:: :icon:`fa-solid fa-image` Image
:link: map-image.html

.. grid-item::

.. card:: :icon:`fa-solid fa-map` FeatureCollection
:link: map-featurecollection.html



In all these examples we will use the object interface of matplotlib creating the :py:class:`Figure <matplotlib.figure.Figure>` and :py:class:`Axes <matplotlib.axes.Axes>` object before plotting the data. This is the recommended way to use matplotlib as it gives you more control over the plot and the figure.

.. code-block:: python
# custom image for this specific chart
modisSr = (
ee.ImageCollection("MODIS/061/MOD09A1")
.filter(ee.Filter.date("2018-06-01", "2018-09-01"))
.select(["sur_refl_b01", "sur_refl_b02", "sur_refl_b06"])
.mean()
)
histRegion = ee.Geometry.Rectangle([-112.60, 40.60, -111.18, 41.22])
#create a matplotlib figure
fig, ax = plt.subplots(figsize=(10, 4))
# plot the histogram of the reds
modisSr.geetools.plot_hist(
bands = ["sur_refl_b01", "sur_refl_b02", "sur_refl_b06"],
labels = [['Red', 'NIR', 'SWIR']],
colors = ["#cf513e", "#1d6b99", "#f0af07"],
ax = ax,
bins = 100,
scale = 500,
region = histRegion,
)
# once created the axes can be modified as needed using pure matplotlib functions
ax.set_title("Modis SR Reflectance Histogram")
ax.set_xlabel("Reflectance (x1e4)")
.. image:: ../../_static/usage/plot/index/histogram.png
:alt: Modis SR Reflectance Histogram
:align: center

If you are used to the :py:mod:`pyplot <matplotlib.pyplot>` interface of matplotlib you can still use it with the state-base module of matplotlib. Just be aware that the module is a stateful interface and you will have less control over the figure and the plot.

.. code-block:: python
# get all hydroshed from the the south amercias within the WWF/HydroATLAS dataset.
region = ee.Geometry.BBox(-80, -60, -20, 20);
fc = ee.FeatureCollection('WWF/HydroATLAS/v1/Basins/level04').filterBounds(region)
# create the plot
fc.geetools.plot(property="UP_AREA", cmap="viridis")
# Customized display
plt.colorbar(ax.collections[0], label="Upstream area (km²)")
plt.title("HydroATLAS basins of level4")
plt.xlabel("Longitude (°)")
plt.ylabel("Latitude (°)")
.. image:: ../../_static/usage/plot/index/hydroshed.png
:alt: HydroATLAS basins of level4
:align: center
88 changes: 17 additions & 71 deletions docs/usage/plot/map-featurecollection.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -115,46 +115,13 @@
"\n",
"A single property can be ploted on a map using matplotlib. The following example is showing the bassin area in km².\n",
"\n",
"First create a matplotlib figure and axis:\n"
"First create a matplotlib figure and axis, then you can add the bassins to the map using the `plot` method. By default it will display the first property of the features. In our case we will opt to display the area of the bassins in km² i.e. the \"UP_AREA\" property. Finally that we have the plot, we can customize it with matplotlib. For example, we can add a title and a colorbar."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"plt.ioff() # remove interactive for the sake of the example\n",
"fig, ax = plt.subplots(figsize=(10, 10))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then you can add the bassins to the map using the `plot` method. By default it will display the first property of the features. In our case we will opt to display the area of the bassins in km² i.e. the \"UP_AREA\" property."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"fc.geetools.plot(ax=ax, property=\"UP_AREA\", cmap=\"viridis\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now that we have the plot, we can customize it with matplotlib. For example, we can add a title and a colorbar."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
Expand All @@ -168,13 +135,19 @@
}
],
"source": [
"# create the plot\n",
"fig, ax = plt.subplots(figsize=(10, 10))\n",
"\n",
"# generate the graph\n",
"fc.geetools.plot(ax=ax, property=\"UP_AREA\", cmap=\"viridis\")\n",
"\n",
"# you can then customize the figure as you would for any other matplotlib object\n",
"fig.colorbar(ax.collections[0], label=\"Upstream area (km²)\")\n",
"ax.set_title(\"HydroATLAS basins of level4\")\n",
"ax.set_xlabel(\"Longitude (°)\")\n",
"ax.set_ylabel(\"Latitude (°)\")\n",
"\n",
"display(fig)"
"plt.show()"
]
},
{
Expand All @@ -185,45 +158,12 @@
"\n",
"Alternatively if you only want to plot the geometries of the featurecollection on a map, you can use the `plot` method with the `boundares` parameter set to `True`.\n",
"\n",
"Similarly to the previous example we start by creating a pyplot figure and axis:"
"Similarly to the previous example we start by creating a pyplot figure and axis, then you can start plotting the geometries and finally customize the plot."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"plt.ioff() # remove interactive for the sake of the example\n",
"fig, ax = plt.subplots(figsize=(10, 10))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then you can start plotting the geometries:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"fc.geetools.plot(ax=ax, boundaries=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and finally customize the plot:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 7,
"metadata": {},
"outputs": [
{
Expand All @@ -238,12 +178,18 @@
}
],
"source": [
"plt.ioff() # remove interactive for the sake of the example\n",
"fig, ax = plt.subplots(figsize=(10, 10))\n",
"\n",
"# create the graph\n",
"fc.geetools.plot(ax=ax, boundaries=True)\n",
"\n",
"# you can then customize the figure as you would for any other matplotlib object\n",
"ax.set_title(\"Borders of the HydroATLAS basins of level4\")\n",
"ax.set_xlabel(\"Longitude (°)\")\n",
"ax.set_ylabel(\"Latitude (°)\")\n",
"\n",
"display(fig)"
"plt.show()"
]
},
{
Expand Down
137 changes: 37 additions & 100 deletions docs/usage/plot/map-image.ipynb

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion geetools/ee_feature_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ def plot_hist(

def plot(
self,
ax: Axes,
ax: Axes | None = None,
property: str = "",
crs: str = "EPSG:4326",
cmap: str = "viridis",
Expand Down Expand Up @@ -460,6 +460,9 @@ def plot(
fig, ax = plt.subplots()
fc.geetools.plot("ADM2_CODE", ax)
"""
if ax is None:
fig, ax = plt.subplots()

# get the data from the server
names = self._obj.first().propertyNames()
names = names.filter(ee.Filter.stringStartsWith("item", "system:").Not())
Expand Down
Loading

0 comments on commit 1273b71

Please sign in to comment.