holoviz / holoviews

With Holoviews, your data visualizes itself.
https://holoviews.org
BSD 3-Clause "New" or "Revised" License
2.66k stars 396 forks source link

Hover over a GeoPandas line feature highlights single segment, not the whole line #5949

Open emiliom opened 8 months ago

emiliom commented 8 months ago

ALL software version info

(this library, plus any other relevant software, e.g. bokeh, python, notebook, OS, browser, etc)

bokeh                     2.4.3           py310hff52083_0    conda-forge
geopandas                 0.14.0             pyhd8ed1ab_0    conda-forge
geopandas-base            0.14.0             pyha770c72_0    conda-forge
geoviews                  1.9.6              pyhd8ed1ab_0    conda-forge
geoviews-core             1.9.6              pyha770c72_0    conda-forge
holoviews                 1.17.1             pyhd8ed1ab_0    conda-forge
hvplot                    0.8.4              pyhd8ed1ab_1    conda-forge
python                    3.10.12         hd12c33a_0_cpython    conda-forge

# The issue also occurs with older versions of some of the libraries:
bokeh                     2.4.3           py310hff52083_0    conda-forge
geopandas                 0.11.1             pyhd8ed1ab_0    conda-forge
geopandas-base            0.11.1             pyha770c72_0    conda-forge
geoviews                  1.9.5              pyhd8ed1ab_0    conda-forge
geoviews-core             1.9.5              pyha770c72_0    conda-forge
holoviews                 1.15.0             pyhd8ed1ab_0    conda-forge
hvplot                    0.8.1              pyhd8ed1ab_0    conda-forge
python                    3.10.6          ha86cf86_0_cpython    conda-forge

I tried to create a fresh conda environment just now that would use the latest libraries (including bokeh 3), but ran into dependency conflicts with both conda and mamba.

Description of expected behavior and the observed behavior

In a holoview (or geoviews / hvplot) plot of a GeoPandas line GeoDataFrame, when hovering over one of the line features, I’d like to highlight (using hover_line_color) the entire line feature. Instead, only the individual line segment is highlighted (that is, a segment that is part of the line feature). In contrast, a polygon GeoDataFrame feature behaves as expected: the entire polygon is highlighted when hovering over it.

I haven’t found a way to highlight the entire line feature, or documentation that says that’s not possible. I asked about this on the discourse forum and was told this is likely a bug and I should submit a but report.

Here’s a Jupyter notebook in a gist that demonstrates this. Note that while the example uses hvplot on a GeoDataFrame, the same behavior is observed after converting from the GeoPandas GeoDataFrame to a geoviews Path or a Spatialpandas GeoDataFrame, or when removing geo=True.

Complete, minimal, self-contained example code that reproduces the issue

import geopandas as gpd
import hvplot.pandas

# two line features, each with two segments
geojson_features = [
    {"type": "Feature", "properties": {"id": 19}, "geometry": {"type": "LineString", "coordinates": [[140.51, 4.40], [140.59, 4.33], [140.62, 4.29]]}}, 
    {"type": "Feature", "properties": {"id": 20}, "geometry": {"type": "LineString", "coordinates": [[140.61, 4.39], [140.65, 4.37], [140.69, 4.33]]}}
]
line_gdf = gpd.GeoDataFrame.from_features(geojson_features)

line_gdf.hvplot(
    color='black',
    hover_line_color='red',
    tools=['hover'], 
    hover_cols=['id'], 
)

Stack traceback and/or browser JavaScript console output

N/A.

Screenshots or screencasts of the bug in action

Please see the notebook gist I prepared, which shows the issue in action.

ahuang11 commented 8 months ago

Just to add a screenshot, notice that although the top left line is highlighted, the bottom left is not.

image
emiliom commented 8 months ago

Thanks @ahuang11. That screenshot illustrates the issue nicely.

emiliom commented 5 months ago

I wanted to add a related issue that impacts the hover tool and overall plot responsiveness when a hover tool is present. A hover tooltip is activated at each line segment that makes up the line, rather than only one per line. When there is a large number of individual segments, even if there are just a handful of lines (ie, the GeoDataFrame has just a few records), there's a noticeable slowdown in many of the plot actions, like zoom, pan, and even just the initial rendering of the element. Having a hover tool in those cases is essentially impractical. Without the hover tool (hover=False in hvplot), the responsiveness issue goes away.

The root cause of the hover tool behavior and hover_line_color behavior is the same: each line feature is apparently being exploded into its component line segments behind the scenes, rather than being treated as a single object. Polygons, in contrast, are handled correctly as single objects.

ahuang11 commented 5 months ago

Here's it in plain HoloViews:

import geopandas as gpd
import holoviews as hv
hv.extension("bokeh")

# two line features, each with two segments
geojson_features = [
    {"type": "Feature", "properties": {"id": 19}, "geometry": {"type": "LineString", "coordinates": [[140.51, 4.40], [140.59, 4.33], [140.62, 4.29]]}}, 
    {"type": "Feature", "properties": {"id": 20}, "geometry": {"type": "LineString", "coordinates": [[140.61, 4.39], [140.65, 4.37], [140.69, 4.33]]}}
]
line_gdf = gpd.GeoDataFrame.from_features(geojson_features)

hv.Path(line_gdf).opts(tools=["hover"])
emiliom commented 5 months ago

Thanks. But the behavior of the hover tool and hover_line_color is still the same: by individual segments.

Update: with hv.Curve instead of hv.Path, things get interesting! Adding hover_line_color='blue' to opts, all lines are now highlighted (blue) when one is hovered over, and a single hover tooltip is displayed. This isn't the behavior I'm looking for, but previous tests had pointed me to exploring a conversion to hv.Curve and possibly using an NdOverlay of Curve elements, one per line. That's not straightforward and may have undesired side effects, but I'll try to look into it.