pylandstats
pylandstats copied to clipboard
Error with compute_class_metrics_df
- PyLandStats version: 2.3.0
- Python version: 3.9
- Operating System: Linux (inside Docker)
Description
I have a small .tif file and I'm trying to compute patch and class-level metrics with PyLandStats
using the methods compute_patch_metrics_df
and compute_class_metrics_df
. I can successfully use compute_patch_metrics_df
which returns:
class_val area perimeter perimeter_area_ratio shape_index fractal_dimension euclidean_nearest_neighbor
patch_id
0 2 1.607143e-08 0.122938 7.649463e+06 2.400000 0.797257 0.002561
1 2 1.639942e-10 0.005122 3.123531e+07 1.000000 1.000000 0.024733
2 2 1.013484e-07 0.274049 2.704027e+06 2.140000 0.777663 0.032724
3 2 3.279884e-10 0.007684 2.342648e+07 1.000000 0.990673 0.002561
4 2 1.459548e-08 0.117815 8.072046e+06 2.421053 0.798199 0.010325
... ... ... ... ... ... ... ...
169 43 6.559767e-10 0.012806 1.952207e+07 1.250000 0.962605 0.002864
170 43 1.475948e-09 0.017928 1.214706e+07 1.166667 0.972284 0.002561
171 43 3.279884e-10 0.007684 2.342648e+07 1.000000 0.990673 0.004050
172 43 3.279884e-10 0.007684 2.342648e+07 1.000000 0.990673 0.004050
173 44 2.469096e-06 0.952768 3.858772e+05 1.512195 0.775226 NaN
[174 rows x 7 columns]
However I get an error with using compute_class_metrics_df
(regardless of the input raster). The error is:
Traceback (most recent call last):
File "/usr/src/app/ecomap/tests.py", line 278, in test_pylandstats
y = ls.compute_class_metrics_df()
File "/usr/local/lib/python3.9/site-packages/pylandstats/landscape.py", line 2616, in compute_class_metrics_df
{
File "/usr/local/lib/python3.9/site-packages/pylandstats/landscape.py", line 2617, in <dictcomp>
class_val: getattr(self, metric)(
File "/usr/local/lib/python3.9/site-packages/pylandstats/landscape.py", line 1240, in total_edge
self._adjacency_df.groupby(
File "/usr/local/lib/python3.9/site-packages/pandas/core/frame.py", line 4308, in drop
return super().drop(
File "/usr/local/lib/python3.9/site-packages/pandas/core/generic.py", line 4153, in drop
obj = obj._drop_axis(labels, axis, level=level, errors=errors)
File "/usr/local/lib/python3.9/site-packages/pandas/core/generic.py", line 4188, in _drop_axis
new_axis = axis.drop(labels, errors=errors)
File "/usr/local/lib/python3.9/site-packages/pandas/core/indexes/base.py", line 5591, in drop
raise KeyError(f"{labels[mask]} not found in axis")
KeyError: '[None] not found in axis'
Is this error user error on my part or some other issue related to the code in PyLandStats
? I've included one of the rasters which creates the above error.
from pylandstats import Landscape
ls = Landscape('/data/tests/testraster.tif')
x = ls.compute_patch_metrics_df() # Executes successfully
print(x)
y = ls.compute_class_metrics_df() # Described error here
print(y)
Thank you! testraster.tif.zip
I have been able to successfully run compute_class_metrics_df()
by loading in the raster via rioxarrary
:
from pylandstats import Landscape
import rioxarray as rxr
raster = rxr.open_rasterio("/Users/simontarr/Downloads/testraster2.tif", masked=True).squeeze()
raster = raster.astype(int)
# Load in raster as rioxarray
ls=Landscape(raster.values, res=(len(raster.x),len(raster.y)))
x = ls.compute_patch_metrics_df()
print('PATCH METRICS \n', x)
y = ls.compute_class_metrics_df(['total_area', 'proportion_of_landscape', 'number_of_patches']) # Described error here
print('CLASS METRICS \n', y)
Hello @simon-tarr,
thank you for using pylandstats and reporting this. It seems that the problem is that the raster that you have sent does not have a nodata value, hence rasterio assigns a Python None
to such value, which is then problematic when pylandstats deals with the pixel adjacency matrix. From your second message, I suppose that rioxarray deals with it differently, also maybe because of the masked=True
argument.
I will assess whether I should add a patch to pylandstats to avoid this situation, since although the raster's metadata is problematic, pylandstats should be able to at least give a more informative error. In the meantime, you can use the following workaround:
ls = pls.Landscape('testraster.tif', nodata=0)
Thank you again. Best, Martí
Hey @martibosch, sorry about my very slow reply - I got caught up on another project and had to put my pylandstats
work on the back burner. Thanks for your explanation about what was causing the error, makes sense! The workaround is appreciated!
Same errors there. The workaround is nice, and a patch to fix the metadata reading is also much appreciated, thanks.
Hello @simon-tarr,
thank you for using pylandstats and reporting this. It seems that the problem is that the raster that you have sent does not have a nodata value, hence rasterio assigns a Python
None
to such value, which is then problematic when pylandstats deals with the pixel adjacency matrix. From your second message, I suppose that rioxarray deals with it differently, also maybe because of themasked=True
argument.I will assess whether I should add a patch to pylandstats to avoid this situation, since although the raster's metadata is problematic, pylandstats should be able to at least give a more informative error. In the meantime, you can use the following workaround:
ls = pls.Landscape('testraster.tif', nodata=0)
Thank you again. Best, Martí
My problem solved with "nodata=0". Thanks.