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

Rasterized NdOverlay uses ImageStack only on an anti-aliased Curve #6187

Open
maximlt opened this issue Apr 12, 2024 · 0 comments
Open

Rasterized NdOverlay uses ImageStack only on an anti-aliased Curve #6187

maximlt opened this issue Apr 12, 2024 · 0 comments
Labels
type: bug Something isn't correct or isn't working

Comments

@maximlt
Copy link
Member

maximlt commented Apr 12, 2024

Reviewing the modernized Gerrymandering example, I noticed some issues with rasterizing a scatter plot. Some of them are hvPlot issues, but it looks like there's also one issue in HoloViews.

In this example, I create an NdOverlay of Scatter elements and rasterize it with an aggregator. I expected the returned DynamicMap to hold an ImageStack but it doesn't.

import datashader as ds
import holoviews as hv
import pandas as pd
from holoviews.operation.datashader import rasterize
hv.extension('bokeh')

df = pd.DataFrame(
    {
        "time": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        "value": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        "by": ["d", "d", "d", "a", "a", "b", "b", "b", "b", "b"],
    }
)
plots = {k: hv.Scatter(g, 'time', 'value') for k, g in df.groupby('by')}
ndo = hv.NdOverlay(plots, kdims='by')
r = rasterize(ndo, aggregator=ds.count_cat('by'))
r

image

:DynamicMap   []
   :NdOverlay   [by]
      :Image   [time,value]   (time_value Count)

I can get an ImageStack if:

  • It's an NdOverlay of Curve elements
  • line_width is not None
plots = {k: hv.Curve(g, 'time', 'value') for k, g in df.groupby('by')}
ndo = hv.NdOverlay(plots, kdims='by')
r = rasterize(ndo, aggregator=ds.count_cat('by'), line_width=1)
r

image

:DynamicMap   []
   :ImageStack   [time,value]   (a,b,d)

In aggregate._process, commenting out this if statement that looks like to be an optimization path, I can obtain an ImageStack in the first example.

if overlay_aggregate.applies(element, agg_fn, line_width=self.p.line_width):
params = dict(
{p: v for p, v in self.param.values().items() if p != 'name'},
dynamic=False, **{p: v for p, v in self.p.items()
if p not in ('name', 'dynamic')})
return overlay_aggregate(element, **params)

@philippjfr do you happen to know if the optimization provided by overlay_aggregate is still relevant? Datashader changed quite a lot over the past couple of years.

cc @jlstevens @hoxbro

@maximlt maximlt added the type: bug Something isn't correct or isn't working label Apr 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't correct or isn't working
Projects
None yet
Development

No branches or pull requests

1 participant