Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions geoviews/data/geopandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)
from holoviews.core.data.interface import DataError
from holoviews.core.data.spatialpandas import get_value_array
from holoviews.core.dimension import dimension_name
from holoviews.core.dimension import Dimension, dimension_name
from holoviews.core.util import isscalar, unique_array, unique_iterator
from holoviews.element import Path

Expand Down Expand Up @@ -257,24 +257,39 @@ def dimension_type(cls, dataset, dim):
else:
return float

@classmethod
def _resolve_dimension(cls, dataset, dim):
"""
Resolves a dimension spec to a Dimension of the dataset.

A Dimension built from a string spec (e.g. by a ``dim('name')``
expression) carries the name as its label, and Dimension equality
compares labels, so it would not match a dimension with a custom
label. Fall back to looking up the name, which matches both names
and labels.
"""
resolved = dataset.get_dimension(dim)
if resolved is None and isinstance(dim, Dimension):
resolved = dataset.get_dimension(dim.name)
return resolved

@classmethod
def isscalar(cls, dataset, dim, per_geom=False):
"""
Tests if dimension is scalar in each subpath.
"""
dim = dataset.get_dimension(dim)
dim = cls._resolve_dimension(dataset, dim)
geom_dims = cls.geom_dims(dataset)
if dim in geom_dims:
return False
elif per_geom:
return all(isscalar(v) or len(list(unique_array(v))) == 1
for v in dataset.data[dim.name])
dim = dataset.get_dimension(dim)
return len(dataset.data[dim.name].unique()) == 1

@classmethod
def range(cls, dataset, dim):
dim = dataset.get_dimension(dim)
dim = cls._resolve_dimension(dataset, dim)
geom_dims = cls.geom_dims(dataset)
if dim in geom_dims:
col = cls.geo_column(dataset.data)
Expand Down Expand Up @@ -356,7 +371,7 @@ def redim(cls, dataset, dimensions):

@classmethod
def values(cls, dataset, dimension, expanded=True, flat=True, compute=True, keep_index=False):
dimension = dataset.get_dimension(dimension)
dimension = cls._resolve_dimension(dataset, dimension)
geom_dims = dataset.interface.geom_dims(dataset)
data = dataset.data
isgeom = (dimension in geom_dims)
Expand Down
20 changes: 20 additions & 0 deletions geoviews/tests/data/test_geopandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,23 @@ def test_geopandas_dataframe_with_different_dtype_column(self):
)
gdf = geopandas.GeoDataFrame(df, geometry=geopandas.points_from_xy(df.x, df.y))
render(Points(gdf))

def test_geopandas_vdim_with_custom_label_resolved_by_name(self):
# Fix for https://github.com/holoviz/geoviews/issues/840
# A dim() expression carries a Dimension whose label is the column
# name, which must still resolve against a vdim with a custom label.
from holoviews import dim
gdf = geopandas.GeoDataFrame(
{"status": ["safe", "endangered", "safe"]},
geometry=geopandas.points_from_xy([0, 1, 2], [0, 1, 2]),
)
points = Points(gdf, vdims=[("status", "Conservation Status")])
probe = dim("status").dimension
assert self.interface.isscalar(points, probe, per_geom=True)
assert_data_equal(
self.interface.values(points, probe),
np.array(["safe", "endangered", "safe"], dtype=object),
)
assert self.interface.range(points, probe) == ("endangered", "safe")
color = dim("status").categorize({"safe": "green", "endangered": "red"})
render(points.opts(color=color))