Setting consistent scatter plot y-axis range and heatmap colorbar range

tl;dr: how do I set the scatter plot y-axis and heatmap colorbar range so they stay the same (0-100) regardless of filter inputs? I’ve tried explicitly setting 1) tickvals/ticktext and 2) the colorbar rgb values.

Longer version:

I’ve created a multi-page analytics dash app with filters that culminate into a heatmap and scatter graph (among other visuals).

I’m having a variation on the same issue with both visuals. In analytics/data science, it’s important to maintain a consistent output range in order to safeguard from skewing the interpretation of the visualizations.

With the heatmap, the colorbar changes to reflect the range of the heatmap values. I’ve tried explicitly declaring the color scale and the colorbar tickvals/ticktext to no avail.

@app.callback(Output('units_graph', 'figure'),
              [Input('store', 'data'),
               Input('facility_names', 'value'),
               Input('unit_names', 'value')])
              
def make_units_graph(dataf, facility, units): 
    
    #dff = filter_dataframe(facility, units, topics, cms, start, end)
    dff = pd.DataFrame.from_records(dataf, columns=cols)
    dff = dff.groupby(by=['Unit Location', 'Received Date'],as_index=False)['Top Response %'].mean()

    #dff['Top Response %'] = dff['Top Response %']*100
    #dff['Top Response %'] = dff['Top Response %'].round()
    dff = dff.set_index('Received Date')
             
    dff['QY'] = pd.to_datetime(dff.index).sort_values().to_period('Q') 

    table = pd.pivot_table(dff, index='Unit Location',
                           columns='QY', values='Top Response %', aggfunc={'Top Response %':np.mean}) #, fill_value=0)

    #color_scale = cl.scales['11']['div']['RdYlGn']
    
    color_scale = [
        [0, 'rgb(165,0,38)'], #0 
        [.1, 'rgb(215,48,39)'], #.1
        [.2, 'rgb(244,109,67)'], #.2
        [.3, 'rgb(253,174,97)'], #.3
        [.4, 'rgb(254,224,139)'], #.4
        [.5, 'rgb(255,255,191)'], #.5 
        [.6, 'rgb(217,239,139)'], #.6
        [.7, 'rgb(166,217,106)'], #.7
        [.8, 'rgb(102,189,99)'], #.8
        [.9, 'rgb(26,152,80)'], #.9
        [1., 'rgb(0,104,55)'], #1
        ]

    heat = go.Heatmap(
           z=table.values.tolist(),
           x=table.columns.astype(str),
           y=table.index, colorscale = color_scale,
           colorbar = dict(tickvals=[0, .2, .4, .6, .8, 1],
                           ticktext = ['0%', '20%', '40%', '60%', '80%', '100%'],
                           ),
                          )
        
    layout = go.Layout(
        title = facility + ' Unit Ratings', 
        hovermode='closest',
        orientation = 90,
        autosize = True,
        xaxis= {'title': ''}
    )

    return go.Figure(data=heat, layout=layout)

output:
heatmap1
heatmap2

I also tried the tickvals/ticktext with the scatter plot to no avail (only copying layout code here):

layout = go.Layout(
        title = 'Facility Scores', 
        hovermode='closest',
        orientation = 90,
        autosize = True,
        xaxis= {'title': ''},
        yaxis = go.layout.YAxis(
                tickmode = 'array',
                tick0 = 0,
                dtick = 20,
                tickvals = [0, 20, 40, 60, 80, 100],
                ticktext = ['0%', '20%', '40%', '60%', '80%', '100%'],
                ),
            )

Output:
scatter2

Please help!

side note: as a data scientist, I love working with dash <3

Hi @beccamayers for the Heatmap you need to set the zmin and zmax value as in

import plotly.graph_objects as go
import numpy as np
z = np.random.random((5, 5)) + 1
fig = go.Figure(go.Heatmap(z=z, zmin=0, zmax=3))
fig.show()

For the Scatter plot, it’s the range parameter of yaxis:

yaxis = dict(range=(0, 100), ...)

Hope his helps.

2 Likes

Thank you, Emmanuelle. Your advice worked for the scatter plot and the heatmap.