Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Annotated Heatmap Sorting

Hello,

I have created an annotated heatmap within Dash, however the input text/values which are passed are displayed in a different order than which they are submitted. I have been looking through attributes and methods, but I have not found anything which would allow me to force the heatmap to follow the same order as the input data.

This is the text array which is submitted immediately before calling the heatmap.

this is an image of two heatmaps made off of similar data created in the same manner and passed in the same order.

Clearly neither heatmap aligns with each other, isn’t based off of value, and is out of order with the passed data.
I have confirmed that the data passed is in the correct order and that the values align with the text.

ps. Also thanks for making such a cool set of tools! I really like dash so far!

1 Like

@WolVes Since you did not post any code I suspect that you expected that ‘Asian’ to be displayed in the upper left corner. When you define a Plotly heatmap with z-value a numpy array, val, of shape (m,n), the position of val[0,0] is in the left lower corner of the heatmap, not the left upper corner as in matplotlib. Hence the first row in the numpy array val is the lower row in the heatmap. The annotation text follows the same rule.

If you want to be displayed as in the posted text, then assign z=np.flipud(val), and set the annotation text from np.flipud(your_text_array).

Ahh, gotcha. That makes since. Your assumption was correct. Ill give that a go. Thanks for your help.

Much more simple is however to use the val as z value and define layout['yaxis'] with autorange=‘reversed’, i.e. something like this:

yaxis=YAxis(
    title='your_title',
    autorange='reversed',
    showgrid=True,   
    autotick=False,  
    dtick=1          
),
1 Like

Can you share the complete code here please

@azharz4u Here is a three year old example: https://plot.ly/~empet/14772/annotated-heatmap/ that is still valid from the point of view of annotated heatmap.

Hi WolVes,

I am working on a similar project but I happen to be stuck at a far earlier stage than you. Would it be possible for you to share your source code with us please? It will probably be extremely helpful to see how you tackled this.

Thank you,

Claudio

This is some cut and pastes from my code. So it’s not complete, but just about everything you need is present. Let me know if you need any more help. Dash is very simple once you get the gist of it.

import pandas as pd
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.figure_factory as ff
import math

#initialize App
app = dash.Dash()
app.css.append_css({'external_url': 'https://cdn.rawgit.com/plotly/dash-app-stylesheets/2d266c578d2a6e8850ebce48fdb52759b2aef506/stylesheet-oil-and-gas.css'})  # noqa: E501

app.layout = html.Div(
    [
        html.Div(
            [
                 html.Div(
                     [
                         dcc.Graph(id='big-map'),
                     ],
                     className = 'six columns'
                 )                
             ],
             className = 'row'
         )
    ],
    className='ten columns offset-by-one'
)

@app.callback(
    dash.dependencies.Output('big-map', 'figure'),
    [dash.dependencies.Input('type-select', 'value'),
     dash.dependencies.Input('small-select', 'value'),
     dash.dependencies.Input('DD', 'value')])
def big_build(type_select, id_, s):    
    
    "Manipulation code based on above inputs" 

    mean_data = "a pd.series with mean values and index values which are the annotations." 

    vals = np.array(mean_data.tolist())
    vals = np.resize(vals, (math.ceil(len(vals))//5, 5))
    vals = np.flipud(vals)

    vals_text = np.array(mean_data.index.tolist())
    vals_text = np.resize(vals_text, (math.ceil(len(vals_text))//5, 5))
    vals_text = np.flipud(vals_text)
    
    fig = ff.create_annotated_heatmap(vals, annotation_text = vals_text, zmin = 0)   
    
    fig.layout.margin.update({
        "l": 5,
        "r": 0,
        "b": 100,
        "t": 80,
        "pad": 0
    })
    
    return fig
2 Likes