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

Support grabbing the label (and group?) for each subcoordinate_y plot from the NdOverlay key #6028

Open
droumis opened this issue Dec 11, 2023 · 4 comments · May be fixed by #6209
Open

Support grabbing the label (and group?) for each subcoordinate_y plot from the NdOverlay key #6028

droumis opened this issue Dec 11, 2023 · 4 comments · May be fixed by #6209
Assignees
Labels
tag: feature: subcoordinate_y type: enhancement Minor feature or improvement to an existing feature

Comments

@droumis
Copy link
Member

droumis commented Dec 11, 2023

As @philippjfr described here, HoloViews should support grabbing the label for each subcoordinate_y plot from the NdOverlay key.

so something like this should just work:

import numpy as np
import holoviews as hv; hv.extension('bokeh')
from scipy.stats import gaussian_kde

categories = ['A', 'B', 'C', 'D', 'E']
data = {cat: np.random.normal(loc=i-2, scale=1.0, size=100) for i, cat in enumerate(categories)}
x = np.linspace(-5, 5, 100)

areas = {}
for i, (cat, values) in enumerate(data.items()):
    pdf = gaussian_kde(values)(x)
    
    area = hv.Area((x, pdf)).opts( # Not having to add a label per subplot
        subcoordinate_y=True, 
        subcoordinate_scale=1.5,
    )
    areas[cat] = area

ridge_plot_areas = hv.NdOverlay(areas).opts(
    width=900,
    height=400,
)

And produced something like this

image
@droumis droumis added the TRIAGE Needs triaging label Dec 11, 2023
@hoxbro hoxbro added type: enhancement Minor feature or improvement to an existing feature and removed TRIAGE Needs triaging labels Dec 15, 2023
@droumis droumis changed the title Support grabbing the label for each subcoordinate_y plot from the NdOverlay key Support grabbing the label for each subcoordinate_y plot from the NdOverlay key. Also reverse layering Feb 5, 2024
@droumis
Copy link
Member Author

droumis commented Feb 5, 2024

Just checking which of my issues are still valid.

This is still a valid issue.

@droumis
Copy link
Member Author

droumis commented Apr 2, 2024

I'm closing this.. I am no longer convinced that this is obvious behavior.. For instance.. what if the key in the dict conflicts with a provided label? I don't think it's that much more work to just set the label per element

@droumis droumis closed this as completed Apr 2, 2024
@philippjfr philippjfr reopened this Apr 2, 2024
@philippjfr
Copy link
Member

I do think this is important, often you will create this view by grouping a dataset by some dimension and those operations will produce an NdOverlay with the values along that dimension (e.g. channels). Adding labels would be pretty cumbersome.

@droumis droumis changed the title Support grabbing the label for each subcoordinate_y plot from the NdOverlay key. Also reverse layering Support grabbing the label for each subcoordinate_y plot from the NdOverlay key Apr 2, 2024
@droumis
Copy link
Member Author

droumis commented Apr 2, 2024

I'm trying to think through the implementation of this a bit more.

My interpretation of what you mean by 'grouping a dataset by some dimension' is something like calling .overlay, correct?

Here is one possible simplified implementation, which of course doesn't yet work with subcoordinate_y because we cannot yet implicitly set the label are per curve.

import numpy as np
import holoviews as hv
import xarray as xr
hv.extension('bokeh')

n_channels = 10
n_seconds = 5
total_samples = 256*n_seconds

time = np.linspace(0, n_seconds, total_samples)
data = np.random.randn(n_channels, total_samples).cumsum(axis=1)
channels = [f"EEG {i}" for i in range(n_channels)]

data_xr = xr.DataArray(data, dims=['channel', 'time'], coords={'channel': channels, 'time': time}, name='value')
curves = hv.Dataset(data_xr).to(hv.Curve, 'time', 'value', 'channel').overlay('channel').opts(
    hv.opts.Curve(
        tools=['hover'],
        # subcoordinate_y=True # Currently requires a unique label per item
    ),
    hv.opts.NdOverlay(
        responsive=True,
        aspect=3,
    )
)
curves

image

I guess in this case, the fix would be for NdOverlay to grab the channel value as the label.

But then if we are trying to avoid for loops entirely, what would be a good approach to setting the group per Curve?

I tried the following but HoloViews doesn't support such complexity:

import numpy as np
import xarray as xr
import holoviews as hv
hv.extension('bokeh')

n_channels = 10
n_seconds = 5
total_samples = 256 * n_seconds
groups = ['A', 'B', 'C']

time = np.linspace(0, n_seconds, total_samples)
data = np.random.randn(n_channels, total_samples).cumsum(axis=1)
channels = [f"EEG {i}" for i in range(n_channels)]

channel_groups = [groups[i % len(groups)] for i in range(n_channels)]

data_xr = xr.DataArray(
    data,
    dims=['channel', 'time'], 
    coords={
        'channel': channels, 
        'time': time,
        'group': ('channel', channel_groups)
    },
    name='value'
)

curves = hv.Dataset(data_xr).to(hv.Curve, 'time', 'value', ['channel', 'group']).overlay('channel').opts(
    hv.opts.Curve(
        tools=['hover'],
    ),
    hv.opts.NdOverlay(
        responsive=True,
        aspect=3,
    )
)

curves

It would be really useful to see (at least pseudocode) of what you think would be a good API

@philippjfr philippjfr assigned philippjfr and unassigned maximlt Apr 5, 2024
@droumis droumis changed the title Support grabbing the label for each subcoordinate_y plot from the NdOverlay key Support grabbing the label (and group?) for each subcoordinate_y plot from the NdOverlay key Apr 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tag: feature: subcoordinate_y type: enhancement Minor feature or improvement to an existing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants