Skip to content

zmin and zmax semi-ignored for surfaces (even when zauto=false) #86

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

Closed
filipinascimento opened this issue Dec 8, 2015 · 2 comments
Closed
Assignees
Labels
bug something broken

Comments

@filipinascimento
Copy link

Documentation states:

zauto (boolean)
default: true
Determines the whether or not the color domain is computed with respect to the input data.
zmin (number)
Sets the lower bound of color domain.
zmax (number)
Sets the upper bound of color domain.

However, when used in surfaces, such as displayed in https://plot.ly/~filipinascimento/3/ , zmin and zmax are ignored for the surface color (although, it updates the colorbar). This makes impossible to have two surfaces sharing the same colormap.

@etpinard
Copy link
Contributor

etpinard commented Dec 8, 2015

Bug confirmed. Thanks

@etpinard etpinard added the bug something broken label Dec 8, 2015
@filipinascimento
Copy link
Author

Hello, I made a quick-and-dirty fix for this. This may be useful for someone while we wait for the real fix.

I changed plotly.js/src/traces/surface/convert.js by adding the following code to the update function of SurfaceTrace:

// Add the following code just before:
//    //Save data
//    this.data = data;

    //Workaround for issue: https://github.com/plotly/plotly.js/issues/86
    //Determining the original bounds.
    var rzmin = 0.0;
    var rzmax = 1.0;

    if(z.length>0 && z[0].length>0){
      rzmin = z[0][0];
      rzmax = z[0][0];
    }

    for (var i = 0; i < z.length; i++) {
      for (var j = 0; j < z[i].length; j++) {
        rzmin = Math.min(rzmin,z[i][j]);
        rzmax = Math.max(rzmax,z[i][j]);
      }
    }

    //Rescale colormap indices to account for zmax and zmin.
    colormap.map(function(d){
      d.index = ((d.index)*(data.zmax-data.zmin)+data.zmin-rzmin)/(rzmax-rzmin);
      return d;
    });

    //Simple color linear interpolation function.
    function interpolateColors(torgba,fromrgba,fromIndex,toIndex,desired){
      var m = (desired-fromIndex)/(toIndex-fromIndex);
      var r = m*(torgba[0]-fromrgba[0])+fromrgba[0];
      var g = m*(torgba[1]-fromrgba[1])+fromrgba[1];
      var b = m*(torgba[2]-fromrgba[2])+fromrgba[2];
      var a = m*(torgba[3]-fromrgba[3])+fromrgba[3];
      return [r,g,b,a];
    }

    var lastIndexLEZero = false; 
    var newColormap = [];
    var hasZero = false;
    var hasOne = false;
    for (var i = 0; i < colormap.length; i++) {
      if(colormap[i].index<=0){
        lastIndexLEZero = true;
      }else{
        //Interpolates for index=0.0.
        if(lastIndexLEZero){
          var torgba = colormap[i].rgb;
          var fromrgba = colormap[i-1].rgb;
          var toIndex = colormap[i].index;
          var fromIndex = colormap[i-1].index;
          var intrgba = interpolateColors(torgba,fromrgba,fromIndex,toIndex,0.0);
          newColormap.push({index:0.0, rgb : intrgba});
          lastIndexLEZero=false;
          hasZero=true;
        }
        //Interpolates for index=1.0.
        if(colormap[i].index>=1.0){
          var torgba = colormap[i].rgb;
          var fromrgba = colormap[i-1].rgb;
          var toIndex = colormap[i].index;
          var fromIndex = colormap[i-1].index;
          var intrgba = interpolateColors(torgba,fromrgba,fromIndex,toIndex,1.0);
          newColormap.push({index:1.0, rgb : intrgba});
          hasOne=true;
          break;
        }else{
          newColormap.push(colormap[i]);
        }
      }
    }
    //If endpoints are missing, add them.
    if(!hasZero){
      newColormap.unshift({index:0.0, rgb : newColormap[0].rgb});
    }
    if(!hasOne){
      newColormap.push({index:1.0, rgb : newColormap[newColormap.length-1].rgb});
    }

    colormap=newColormap;

// Continues with:
//    //Save data
//    this.data = data;
//    ...

What I did was rescale the colormap to [zmin,zmax] range, while also clamping the indices between 0 and 1.0. I tried, without success, to change the exported colormap function, but it became troublesome to carry zmin, zmax and the original bounds along all the way down to the texture generation. This may introduce more bugs, but seems to work for various surfaces and colormaps.

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

No branches or pull requests

2 participants