glue-viz / glue

Linked Data Visualizations Across Multiple Files
http://glueviz.org
Other
721 stars 152 forks source link

Preserve alpha while compositing with cmap.set_bad #2468

Closed bmorris3 closed 4 months ago

bmorris3 commented 7 months ago

In https://github.com/glue-viz/glue/pull/2427, we intentionally ensured that image layers had only one alpha. The set_bad([color, alpha]) feature in matplotlib colormaps allows a distinct alpha for “bad” values, which is a really useful feature. This PR allows layers to render colormaps that have "bad" values rendered with their own alpha (possibly distinct from the alpha for pixels that are not "bad"). This feature is implemented with an opt-in flag on the CompositeArray object.

Here's an example of how to use it, with jdaviz:

import numpy as np
from jdaviz import Imviz

# fake "data"
sci = np.random.normal(size=(100, 100))

# fake bitmask:
dq_example = np.random.randint(0, 8, size=sci.shape)
dq_example = dq_example + np.where(
    np.random.uniform(0, 1.1, size=sci.shape).astype(int).astype(bool), 
    0,
    np.nan
)

# load the data and the bitmask into Imviz:
imviz = Imviz()
imviz.load_data(sci)
imviz.load_data(dq_example)
imviz.show(height=900)

po = imviz.plugins['Plot Options']

# use a grayscale colormap on the data 
po.layer = po.layer.choices[0]
po.image_color_mode = 'Colormap'
po.image_colormap = 'Gray'
po.image_opacity = 1

# use reverse rainbow on the bitmask:
po.layer = po.layer.choices[1]
po.image_opacity = 0.8
po.image_colormap = 'Reversed: Rainbow'

viewer = imviz.default_viewer
layer_artist = viewer._obj.layers[-1]  # bitmask layer artist

# set to False to get default behavior (layer.alpha == bad alpha)
layer_artist.axes._composite._allow_bad_alpha = True  

# set "bad" color+alpha to transparent green
layer_artist.state.cmap.set_bad(color='g', alpha=0)
Screen Shot 2023-12-12 at 16 54 49

where the "bad" pixels here are rendered with alpha=0, and the others with layer.alpha. The current behavior on main default behavior can be shown by setting layer_artist.axes._composite._allow_bad_alpha = False:

Screen Shot 2023-12-12 at 16 57 17

where the layer.alpha is identical to the alpha of every pixel, regardless of the bad settings in the matplotlib colormap.

pllim commented 6 months ago

The TestCompositeArray.test_cmap_blending failure looks related?

bmorris3 commented 6 months ago

It is related, I'm working on it.

astrofrog commented 4 months ago

@bmorris3 - have you had a chance to look into the failures? This seems fine to me otherwise and would be happy to try and get this merged in soon.

bmorris3 commented 4 months ago

@astrofrog – as I mentioned on Slack, I could use some help on that.

astrofrog commented 4 months ago

@bmorris3 - ok sounds good, will take a look

astrofrog commented 4 months ago

@bmorris3 - I think the failure should be fixed, let's see if the CI agrees. I think the next step will be to figure out how to expose the opt-in part in the public API so that jdaviz doesn't depend on private API. It might make sense to have a callback property on the image viewer state that controls this (we don't have to expose it in the Qt UI, just on the state class).