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

template.layout.colorscale not applied to heatmap unless autocolorscale is True #3829

Closed
jonmmease opened this issue May 2, 2019 · 5 comments

Comments

@jonmmease
Copy link
Contributor

Consider a heatmap trace with a template that specifies a global default colorscale:

CodePen: https://codepen.io/jonmmease/pen/XQvbge?editors=1010

var fig = {
  "data": [
    {
      "type": "heatmap",
      "x": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "y": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "z": [1, 2, 3, 4, 5, 6, 7, 8, 9],
    }
  ],
  "layout": {
    "template": {
      "layout": {
        "colorscale": {
          "sequential": "Cividis"
        }
      }
    },
    "title": {
      "text": "Colorscale templating test"
    }
  }
}

Plotly.newPlot('myDiv', fig, {showSendToCloud: true});

newplot-7

This template colorscale is not applied. If the template's heatmap autocolorscale property is set to true then the colorscale is applied.

var fig = {
  "data": [
    {
      "type": "heatmap",
      "x": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "y": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "z": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      // "colorscale": "Viridis"
    }
  ],
  "layout": {
    "template": {
      "data": {
        "heatmap": [
          {"autocolorscale": true}
        ]
      },
      "layout": {
        "colorscale": {
          "sequential": "Cividis"
        }
      }
    },
    "title": {
      "text": "Colorscale templating test"
    }
  }
}

Plotly.newPlot('myDiv', fig, {showSendToCloud: true});

newplot-8

but in this case, the colorscale provided in the heatmap trace is ignored.

var fig = {
  "data": [
    {
      "type": "heatmap",
      "x": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "y": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "z": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "colorscale": "Viridis"
    }
  ],
  "layout": {
    "template": {
      "data": {
        "heatmap": [
          {"autocolorscale": true}
        ]
      },
      "layout": {
        "colorscale": {
          "sequential": "Cividis"
        }
      }
    },
    "title": {
      "text": "Colorscale templating test"
    }
  }
}


Plotly.newPlot('myDiv', fig, {showSendToCloud: true});

newplot-8

I don't fully understand the intended behavior of autocolorscale in the case of templates, but I think we need some way to specify a default global colorscale in the template and then be able to override it in the trace without explicitly specifying autocolorscale in the trace.

What do you think?

@etpinard
Copy link
Contributor

etpinard commented May 2, 2019

Related #3100


The problem here isn't with templates, it's how layout.colorscale settings failed to affect the trace autocolorscale default value - see https://codepen.io/etpinard/pen/axedZv Note that autocolorcale defaults to true for all colorscales except "old" traces like heatmap and contour (we needed that to preserve backward compatibility ~ 4 years ago 😄 ).

So, one could argue that whenever layout.colorscale is set, autocolorscale in all traces (old and new) should default to true. The problem here is say we have:

Plotly.newPlot('graph', [{
  type: 'heatmap',
  z: [[-1,2,3], [2,1,4]],
}], {
  colorscale: {
    sequential: 'Viridis'
  }
})

here the colorscale is diverging, meaning that the set colorscale.sequential will never get used: the heatmap will be drawn using RdBu. This case probably doesn't warrant making the heatmap autocolorscale attribute default to true.

I'd be ok in making autocolorscale default to true when all the layout.colorscale.* attributes are set and valid (is that the case in the plotly.py templates?). Otherwise, I think it would be best to wait for a major bump where we could make all traces have autocolorscale:true as their dflt, cutting much of the complexity.

@jonmmease
Copy link
Contributor Author

I don't mind setting autocolorscale: true in the template for these old-style traces. But I would like to make sure that if a user specifies an explicit colorscale in the trace, it overrides this autocolorscale. Here's a case where this doesn't seem to be happening.

var fig = {
  "data": [
    {
      "type": "heatmap",
      "x": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "y": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "z": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "colorscale": "Viridis"
    }
  ],
  "layout": {
    "template": {
      "data": {
        "heatmap": [
          {"autocolorscale": true}
        ]
      },
      "layout": {
        "colorscale": {
          "sequential": "Cividis"
        }
      }
    },
    "title": {
      "text": "Colorscale templating test"
    }
  }
}


Plotly.newPlot('myDiv', fig, {showSendToCloud: true});

newplot (3)

Would you consider this to be a bug?

@etpinard
Copy link
Contributor

etpinard commented May 2, 2019

I wouldn't call this a bug, as your fig should be equivalent to:

var fig = {
  "data": [
    {
      "type": "heatmap",
      "x": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "y": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "z": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "autocolorscale": true,
      "colorscale": "Viridis"
    }
  ],
  "layout": {
    "colorscale": {
      "sequential": "Cividis"
    },
    "title": {
      "text": "Colorscale templating test"
    }
  }
}


Plotly.newPlot('graph', fig, {showSendToCloud: true});

which (and should) renders the heatmap with Cividis. But I understand why this can be annoying.


Now, note that:

var fig = {
  "data": [
    {
      "type": "heatmap",
      "x": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "y": [1, 2, 3, 4, 5, 6, 7, 8, 9],
      "z": [1, 2, 3, 4, 5, 6, 7, 8, 9],
     // "colorscale": "Viridis"
    }
  ],
  "layout": {
    "template": {
      "data": {
        "heatmap": [
          {"autocolorscale": true}
        ]
      },
      "layout": {
        "colorscale": {
          "sequential": "Cividis"
        }
      }
    },
    "title": {
      "text": "Colorscale templating test"
    }
  }
}
Plotly.newPlot(gd, fig)
Plotly.restyle(gd, 'colorscale', 'Viridis')

renders the heatmap with Viridis as restyle adds implicitly sets autocolorscale:false on restyle calls involving colorscale. Sorry to ask, but is that something plotly.py could implement as a workaround?

@jonmmease
Copy link
Contributor Author

Ok, I think I understand now. I was missing the fact that heatmap ignores layout.colorscale if autocolorscale: false and it ignores heatmap.colorscale if autocolorscale: true. So what I'll do is remove autocolorscale: true from the template and repeat the theme's sequential colorscale as heatmap.colorscale in the template.

Thanks for working through it with me. I think I have the knowledge I need now 🙂

@etpinard
Copy link
Contributor

etpinard commented May 3, 2019

No worries @jonmmease !

I'm very much looking forward to making autocolorscale:true the dflt for all trace types in v2.

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

No branches or pull requests

2 participants