title: Using discrete custom color in a plotly heatmap
body: <p>I'm trying to generate a <code>plotly</code> <code>heatmap</code>, where I'd like the colors to be specified by a discrete scale.</p>
  
  <p>Here's what I mean:</p>
  
  <p>Generate data with 2 clusters and hierarchically cluster them:</p>
  
  <pre><code>require(permute)
  set.seed(1)
  mat &lt;- rbind(cbind(matrix(rnorm(2500,2,1),nrow=25,ncol=500),matrix(rnorm(2500,-2,1),nrow=25,ncol=500)),
               cbind(matrix(rnorm(2500,-2,1),nrow=25,ncol=500),matrix(rnorm(2500,2,1),nrow=25,ncol=500)))
  rownames(mat) &lt;- paste("g",1:50,sep=".")
  colnames(mat) &lt;- paste("s",1:1000,sep=".")
  hc.col &lt;- hclust(dist(t(mat)))
  dd.col &lt;- as.dendrogram(hc.col)
  col.order &lt;- order.dendrogram(dd.col)
  hc.row &lt;- hclust(dist(mat))
  dd.row &lt;- as.dendrogram(hc.row)
  row.order &lt;- order.dendrogram(dd.row)
  mat &lt;- mat[row.order,col.order]
  </code></pre>
  
  <p>Brake the values in <code>mat</code> to intervals and set a color for each interval:</p>
  
  <pre><code>require(RColorBrewer)
  mat.intervals &lt;- cut(mat,breaks=6)
  interval.mat &lt;- matrix(mat.intervals,nrow=50,ncol=1000,dimnames=list(rownames(mat),colnames(mat)))
  interval.cols &lt;- brewer.pal(6,"Set2")
  names(interval.cols) &lt;- levels(mat.intervals)
  </code></pre>
  
  <p>Using <code>ggplot2</code> I draw this <code>heatmap</code> this way (also having the <code>legend</code> specify the discrete colors and respective ranges):</p>
  
  <pre><code>require(reshape2)
  interval.df &lt;- reshape2::melt(interval.mat,varnames=c("gene","sample"),value.name="expr")
  require(ggplot2)
  ggplot(interval.df,aes(x=sample,y=gene,fill=expr))+
    geom_tile(color=NA)+theme_bw()+
    theme(strip.text.x=element_text(angle=90,vjust=1,hjust=0.5,size=6),panel.spacing=unit(0.025,"cm"),legend.key=element_blank(),plot.margin=unit(c(1,1,1,1),"cm"),legend.key.size=unit(0.25,"cm"),panel.border=element_blank(),strip.background=element_blank(),axis.ticks.y=element_line(size=0.25))+
    scale_color_manual(drop=FALSE,values=interval.cols,labels=names(interval.cols),name="expr")+
    scale_fill_manual(drop=FALSE,values=interval.cols,labels=names(interval.cols),name="expr")
  </code></pre>
  
  <p>which gives:
  <a href="https://i.stack.imgur.com/awXh4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/awXh4.png" alt="enter image description here"></a></p>
  
  <p>This is my attempt to generate it with <code>plotly</code>:</p>
  
  <pre><code>plot_ly(z=mat,x=colnames(mat),y=rownames(mat),type="heatmap",colors=interval.cols)
  </code></pre>
  
  <p>which gives:</p>
  
  <p><a href="https://i.stack.imgur.com/oYs8k.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oYs8k.png" alt="enter image description here"></a></p>
  
  <p>The figures are not identical. In the <code>ggplot2</code> figure the clusters are much more pronounced in contrast to the <code>plotly</code> figure.</p>
  
  <p>Is there any way to parametrize the <code>plotly</code> command to give something more similar to the <code>ggplot2</code> figure?</p>
  
  <p>Also, is it possible to make the <code>plotly</code> legend discrete - similar to that in the <code>ggplot2</code> figure?</p>
  
  <p>Now suppose I want to <code>facet</code> the clusters. In the <code>ggplot2</code> case I'd do:</p>
  
  <pre><code>require(dplyr)
  facet.df &lt;- data.frame(sample=c(paste("s",1:500,sep="."),paste("s",501:1000,sep=".")),facet=c(rep("f1",500),rep("f2",500)),stringsAsFactors=F)
  interval.df &lt;- left_join(interval.df,facet.df,by=c("sample"="sample"))
  interval.df$facet &lt;- factor(interval.df$facet,levels=c("f1","f2"))
  </code></pre>
  
  <p>And then plot:</p>
  
  <pre><code>ggplot(interval.df,aes(x=sample,y=gene,fill=expr))+facet_grid(~facet,scales="free",space="free",switch="both")+
    geom_tile(color=NA)+labs(x="facet",y="gene")+theme_bw()+
    theme(strip.text.x=element_text(angle=90,vjust=1,hjust=0.5,size=6),panel.spacing=unit(0.05,"cm"),plot.margin=unit(c(1,1,1,1),"cm"),legend.key.size=unit(0.25,"cm"),panel.border=element_blank(),strip.background=element_blank(),axis.ticks.y=element_line(size=0.25))+
    scale_color_manual(drop=FALSE,values=interval.cols,labels=names(interval.cols),name="expr")+
    scale_fill_manual(drop=FALSE,values=interval.cols,labels=names(interval.cols),name="expr")
  </code></pre>
  
  <p>Which gives:
  <a href="https://i.stack.imgur.com/fnRBf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fnRBf.png" alt="enter image description here"></a></p>
  
  <p>So the clusters are separated by the <code>panel.spacing</code> and look even more pronounced. Is there any way to achieve this faceting with <code>plotly</code>?</p>