holoviz/geoviews

Zooming into geoviews plot not working with many gv.points

Michael-Barletta opened this issue ยท 10 comments

ALL software version info

bokeh 3.1.1 pyhd8ed1ab_0 conda-forge
geopandas 0.13.0 pyhd8ed1ab_0 conda-forge
geoviews 1.10.0 pypi_0 pypi
holoviews 1.16.0 pyhd8ed1ab_0 conda-forge

Description of expected behavior and the observed behavior

Have not been able to come up with an MRE to reproduce what I am seeing, but since the latest geoviews/panel updates some of my geoviews plots create this error when zooming into them.

Before Zoom:
image

After Zoom:
image

Zooming in more:
image

This issue only occurs when zooming in with the wheel scroller, when using the box zoom, we get the expected behavior

Zooming with box zoom:
image

This seems to only occur with one plot that I have that has many different points, hence why I am struggling to reproduce the issue. Here is the behavior when zooming in with other plots that have less point data.

Before Zoom:
image

After Zoom:
image

@Michael-Barletta, can you provide what web browser you use (including version number) and output from JS console (full traceback) when the error occurs? Given the behavior showed in the third image, there should be a lot of errors in the console.

hoxbro commented

And if possible also the code used to generate this (even if it is not minimal).

I've encountered this exact problem in the past. I can't remember what fixed it, but do you happen to add a custom colorbar?

@mattpap @TheoMathurin

I am using google chrome 113.0.5672.127
here is a screenshot of the errors I am getting from the JS console as I zoom in.
image

interestingly enough, I am using a custom colorbar, however, I have other outputs that are using a custom colorbar but they are not producing this same issue.

Try removing the colorbar to see if it plays a role.

@Hoxbro @TheoMathurin @mattpap
I've created the MRE and I've narrowed down the problem to the labels that are causing this issue.

Here is the code. When you take away the *labels argument at the very end, everything works fine.

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import geoviews as gv
import panel as pn

gv.extension('bokeh', 'matplotlib')

# Generate random latitude and longitude within CONUS
np.random.seed(42)
latitude = np.random.uniform(24.396308, 49.384358, 60000)  # CONUS latitude range
longitude = np.random.uniform(-125.000000, -66.934570, 60000)  # CONUS longitude range

# Generate random temperature data
temperature = np.random.normal(25, 5, 60000)

# Generate random time stamps rounded to the nearest hour for 24 hours of data
start_time = datetime.now().replace(minute=0, second=0, microsecond=0) - timedelta(days=1)
time_stamps = [start_time + timedelta(hours=i) for i in range(24)]
random_times = np.random.choice(time_stamps, 60000)

# Create DataFrame
df = pd.DataFrame({'Lat': latitude, 'Lon': longitude, 'Temperature': temperature, 'Time': random_times})

# Add column with rounded temperature as string
df['Temperature_r'] = df['Temperature'].round().astype(int).astype(str)

kdims=['Lon','Lat','Time']

vdims = ['Time','Temperature']

df['Temperature'] = df['Temperature'].astype(float)

ds = gv.Dataset(df, kdims=kdims)
plot = (ds.to(gv.Points, ["Lon", "Lat"], vdims=vdims))

labels = ds.to(gv.Labels, kdims=['Lon', 'Lat'],vdims='Temperature_r').opts(
text_font_size='10pt', text_color='white')

pn.panel((plot.opts(frame_width=1600, frame_height=1000, size=35))*labels)
hoxbro commented

Is it not possible to just generate fake data?

  • Where Lon and Lat are limited by the range of the original data.

@Hoxbro

I updated my example with this included, I apologize, I did not realize how easy it was to generate a fake dataset that large, but that example is giving me the same issue.

hoxbro commented

Thank you. @mattpap here is a pure Bokeh example, showing the same behavior:

import numpy as np
from bokeh.io import curdoc, show, output_notebook
from bokeh.models import ColumnDataSource, Text
from bokeh.plotting import figure

output_notebook()

N = 6000
x = np.linspace(-2, 2, N)
y = x**2
text = list(map(str, range(N)))

source = ColumnDataSource(dict(x=x, y=y, text=text))

plot = figure(title=None, width=300, height=300, min_border=0, toolbar_location=None)

glyph = Text(x="x", y="y", text="text", angle=0.3, text_color="#96deb3")
plot.add_glyph(source, glyph)

show(plot)

This was fixed in bokeh/bokeh#13113, which is available in bokeh 3.2.0.dev3.