Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A keyword argument to show individual points when zoomed, else datashade #597

Closed
ahuang11 opened this issue Apr 26, 2021 · 4 comments
Closed
Labels
type: docs type: enhancement New feature or request
Milestone

Comments

@ahuang11
Copy link
Collaborator

ds.hvplot('lon', 'lat', zoom_datashade=True)
I wonder if it'd be possible to create an keyword argument like zoom_datashade=True that calls this
https://discourse.holoviz.org/t/show-individual-points-when-zoomed-else-rasterize/2204

@maximlt maximlt added type: enhancement New feature or request and removed TRIAGE labels Oct 25, 2022
@maximlt
Copy link
Member

maximlt commented Oct 25, 2022

The discussion on Discourse started with this first example that creates an overlay of points and its datashaded version, the points being not displayed over a threshold taken as the number of points contained in the view port (5000 in the example).

import numpy as np
from holoviews.operation.datashader import datashade
import holoviews as hv

hv.extension('bokeh')

points = hv.Points(np.random.multivariate_normal((0,0), [[0.1, 0.1], [0.1, 1.0]], (500000,)))

def filter_points(points, x_range, y_range):
    if x_range is None or y_range is None:
        return points
    return points[x_range, y_range]

def hover_points(points, threshold=5000):
    if len(points) > threshold:
        return points.iloc[:0]
    return points

range_stream = hv.streams.RangeXY(source=points)
streams=[range_stream]

filtered = points.apply(filter_points, streams=streams)
shaded = datashade(filtered, width=400, height=400, streams=streams)
hover = filtered.apply(hover_points)

dynamic_hover = (shaded * hover).opts(
    hv.opts.Points(tools=['hover'], alpha=0.1, hover_alpha=0.2, size=10))

Then Philipp showed that there's the apply_when operation in HoloViews that automatically does the switch between displaying an element and the output of an operation on that element, given a predicate function. So it's not exactly the same output as the code above, since there's no overlay of the points and their datashaded version.

import holoviews as hv

from holoviews.operation.datashader import rasterize
from holoviews.operation import apply_when

points = hv.Points(np.random.randn(100000, 2)).opts(tools=['hover'], alpha=0.1, hover_alpha=0.2, size=10)

# The operation can be customized by creating an instance of it.
my_custom_rasterize = rasterize.instance(x_sampling=0.25, y_sampling=0.25, aggregator="max")

apply_when(points, operation=my_custom_rasterize, predicate=lambda x: len(x) > 5000)

At the time @jbednar said:

I’d be happy to see that in hvplot. Maybe datashade=5000 or rasterize=5000 instead of datashade=True or rasterize=True, indicating that if there are more than 5000 points visible in the current viewport then datashade it, else use raw Bokeh plotting? There are various complications like categorical plotting (supported very differently in datashader and bokeh), styling (colors, sizes, etc.). But in principle, yes.

When I started to work on hvPlot I thought that hvPlot users should pretty much never have to interact with HoloViews directly. I've changed my mind on this topic, I believe there are specific parts of HoloViews that are simple enough to be exposed to hvPlot users, when they need that extra power or more flexibility, and using the operations is I believe one of these areas.

In this particular case I would argue that we first need to document the apply_when operation in hvPlot (it's actually not documented in HoloViews, but that's another issue). Since this has to do with displaying large datasets, I believe hvPlot should have a guide related to plotting large data. it should be a much shorter version of the HoloViews guide on that matter, linking to the HoloViews guide for more information.

  • Create a guide on plotting large data
  • Document apply_when

Imo I think that only after this is completed we could think about adding to hvPlot's API the possibility to directly get this behavior.

@maximlt maximlt added this to the 0.8.x milestone Oct 25, 2022
@jbednar
Copy link
Member

jbednar commented Oct 25, 2022

I support having those docs!

Note that there are hvplot-specific aspects to apply_when and similar cases. In HoloViews, if you try to use it, you'll realize that you need to supply all of your options (line widths, colors, etc.) to the operation as well as separately using hv options. That's pretty awkward, but doesn't necessarily apply to hvPlot, since hvPlot creates both the operation call and the options settings from the same argument list. Thus there is an argument for putting this specific functionality into hvplot's arguments, because we can provide a much better user experience than using the HoloViews API alone.

@maximlt
Copy link
Member

maximlt commented Nov 14, 2022

Related to holoviz/holoviews#5512

@ahuang11
Copy link
Collaborator Author

Implemented in #1103

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: docs type: enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants