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

Per-element opacity on Surface plots (opacityscale) #4331

Closed
nicolaskruchten opened this issue Nov 2, 2019 · 20 comments · Fixed by #4480
Closed

Per-element opacity on Surface plots (opacityscale) #4331

nicolaskruchten opened this issue Nov 2, 2019 · 20 comments · Fixed by #4480
Assignees
Labels
feature something new
Milestone

Comments

@nicolaskruchten
Copy link
Contributor

Requested in plotly/plotly.py#1859

@lucapinello
Copy link
Contributor

I think the problem is related to this function:

function parseColorScale(cont, alpha) {

This function destroy the alpha information and convert the rgba into rgb with the same global opacity for all the colors.

This function is called when parsing the colormap to plot the surface here:

var colormap = parseColorScale(data, alpha);

I am more a Python person, am I on the right track? :)

@nicolaskruchten
Copy link
Contributor Author

I don’t know if “problem” is the word I would use here... At the moment we consciously don’t support alpha in color scales so this is more of a feature request from our perspective today.

There’s also the question of whether or not we can render this correctly and efficiently in webGL with the current code.

@lucapinello
Copy link
Contributor

lucapinello commented Nov 2, 2019

Fair enough.

BTW this fixed the conversion to support the alpha values:

function parseColorScale(cont, alpha) {
if(alpha === undefined) alpha = 1;

var cOpts = Colorscale.extractOpts(cont);

var colorscale = cOpts.reversescale ?
    Colorscale.flipScale(cOpts.colorscale) :
    cOpts.colorscale;

return colorscale.map(function(elem) {
    var index = elem[0];
    var color = tinycolor(elem[1]);
    var rgb = color.toRgb();
	console.log(rgb);
    return {
        index: index,
        **rgb: [rgb.r, rgb.g, rgb.b, rgb.a]**
    };
});

}

But only if you specify a global opacity <1.0. (0.99 does the trick for me and it works really smoothly)

There must be another setting that overrides this when opacity=1.

image

Thanks again for the quick reply and for the support.

@nicolaskruchten
Copy link
Contributor Author

Great! Feel free to submit a pull request, which should cause the tests to run and we’ll see if that shakes anything loose :)

@lucapinello
Copy link
Contributor

Great! Just submitted.

@lucapinello
Copy link
Contributor

lucapinello commented Nov 3, 2019 via email

@archmoj
Copy link
Contributor

archmoj commented Nov 3, 2019

What about implementing opacityscale (similar to volume trace) for surface as well as scatter3d plots?

@lucapinello
Copy link
Contributor

Thanks @archmoj for the feedback. Do you have a link with an example?

@archmoj
Copy link
Contributor

archmoj commented Nov 4, 2019

Thanks @archmoj for the feedback. Do you have a link with an example?

@lucapinello
Please view this demo.
At the moment this feature is only implemented for volume plots.

@lucapinello
Copy link
Contributor

lucapinello commented Nov 4, 2019 via email

@archmoj
Copy link
Contributor

archmoj commented Nov 4, 2019

What about renaming the title of this ticket to mention opacityscale then?

@lucapinello
Copy link
Contributor

Good idea, @nicolaskruchten do you want to change the title in. Implement opacityscale also in Surface as available in Volume and Scatter3D for consistency.

@nicolaskruchten nicolaskruchten changed the title Per-element opacity on Surface plots Per-element opacity on Surface plots (opacityscale) Nov 5, 2019
@etpinard
Copy link
Contributor

@archmoj would adding opacityscale be a valuable addition to the library in your mind?

If so, please tag this ticket with type: feature.

@etpinard
Copy link
Contributor

(not to be confused with #4120)

@archmoj archmoj added the feature something new label Nov 18, 2019
@archmoj archmoj self-assigned this Jan 7, 2020
@archmoj
Copy link
Contributor

archmoj commented Jan 9, 2020

Here is a demo where opacityscale is implemented for surface plots.

@archmoj archmoj added this to the v1.53.0 milestone Jan 9, 2020
@nicolaskruchten
Copy link
Contributor Author

I'm not sure I understand how this opacityscale works... what is it using as data here, z?

@archmoj
Copy link
Contributor

archmoj commented Jan 9, 2020

In regard with opacityscale one could pass an array similar to colorscale replacing colors with alpha values.
For example:

[
  [0, 0.2],
  [0.5, 0.3],
  [1, 0.6]
]

would map the opacity of min color to 0.2, the average to 0.3, and the maximum color to 0.6.
There is also strings keys namely "min", "max" and "extremes" to facilitate declaring this.
E.g. the option of "max" maps to [[0, 0.1], [1, 1]] which fades values that are closer to the minimum.

@nicolaskruchten
Copy link
Contributor Author

It feels like it would be a simpler API to accept the A value of RGBA, no?

@archmoj
Copy link
Contributor

archmoj commented Jan 9, 2020

Well, we could potentially add such an option to colorscale.
However it is the way opacityscale introduced by volume as well as gl-mesh3d webgl module.
It covers all the cases where one needs to use different opacity levels steps free from various steps defined by any colorscale.

@nicolaskruchten
Copy link
Contributor Author

OK, I guess this makes sense. Seems a bit odd to have two separate scales linked to the same value which doesn't share a name with either i.e. z but OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants