Annotated Heatmap in subplots share scaling

Hi! I’m creating a heat map using annotated_heatmap (I know it is deprecated but we use older version of peplos in the project). I managed to create a nice layout I like, but I want to share scaling across different subplots.
For instance, if one subplot has 10 as it greatest value, and the second one has 6, I want 6 to be coloured less vividly than 10.
Is it possible?

Also, plots are built from bottom to top. How can I reverse it?

Hi @yukrl ,
welcome to the community. It might be challenging to do with a deprecated feature, but we’ll try.
Can you please share example code with example data (Minimal Reproducible Example) so we can replicated on our computers. And what version of Plotly are you using?

Sure.

df = pd.DataFrame([[1, 2, 3], [8, 6, 5], [10, 1, 3]])
df = df.rename(columns = {0:'positive', 1:'negative', 2:'neutral'})
df.index = ['a', 'b', 'c']

cm = ['Greens', 'YlOrRd', 'Blues']
fig = make_subplots(rows=1, cols=3, horizontal_spacing=0.0, shared_yaxes=True)
fig.update_yaxes(autorange = 'reversed')
fig.update_xaxes(side = 'top')

tmp = df[['positive']]
fig1 = ff.create_annotated_heatmap(tmp.values,
                        x=tmp.columns.tolist(),
                        y=tmp.index.tolist(),
                        colorscale=cm[0], showscale=False, reversescale=False, opacity=0.75)

tmp = df[['negative']]
fig2 = ff.create_annotated_heatmap(tmp.values,
                        x=tmp.columns.tolist(),
                        y=tmp.index.tolist(),
                        colorscale=cm[1], showscale=False, reversescale=False, opacity=0.75)

tmp = df[['neutral']]
fig3 = ff.create_annotated_heatmap(tmp.values,
                        x=tmp.columns.tolist(),
                        y=tmp.index.tolist(),
                        colorscale=cm[2], showscale=False, reversescale=False, opacity=0.75)

fig.add_trace(fig1.data[0], 1, 1)
fig.add_trace(fig2.data[0], 1, 2)
fig.add_trace(fig3.data[0], 1, 3)

annot1 = list(fig1.layout.annotations)
annot2 = list(fig2.layout.annotations)
annot3 = list(fig3.layout.annotations)

for k  in range(len(n)):
   annot1[k]['xref'] = 'x1'
   annot1[k]['yref'] = 'y1'
for k  in range(len(annot2)):
   annot2[k]['xref'] = 'x2'
   annot2[k]['yref'] = 'y2'
for k  in range(len(annot3)):
    annot3[k]['xref'] = 'x3'
    annot3[k]['yref'] = 'y3'

fig.layout.update(annotations=annot1+annot2+annot3)
         
fig.show()

I actually managed to reverse the y axis so that part of the question is solved.
Thank you.

EDIT: edited the code

EDIT 2: I tried my code on real data and came across the following problem. One of the rows have significantly higher values, that the others, so the colouring looks funny: one row is brightly coloured, the others are almost white. I will consider switching to imshow() if its an easy fix with the new way.

imshow() might work better here, @yukrl .
I can continue working on your code here to see if I can make any progress. Right now I’m getting the error:

fig = make_subplots(rows=1, cols=3, horizontal_spacing=0.0, shared_yaxes=True) 
NameError: name 'make_subplots' is not defined

Can you share that function please.

I’m sorry, I didn’t include imports.

from plotly.subplots import make_subplots
import plotly.figure_factory as ff
import pandas as pd

@yukrl

Does the update:

fig.update_traces(zmin=min of z-values in all subplots, zmax=max of z-values in all subplots) 

generate your desired plot?
For your MWE:

fig.update_traces(zmin=1, zmax=10)

i got this image:
annot-heatmap-sbplts

To get a working solution for any three (or more) colorscales, they must have the same range for lightness. But to ensure such a property you have to install ehtplot GitHub - liamedeiros/ehtplot: Plotting functions for the Event Horizon Telescope, convert the array of rgb color representing each colorscale, to the CAM2-UCS space, and modify the lightness of all colorscales to get the same range.

Yes, that works just as I wanted. Thank you!