How to set log scale for z axis on a heatmap?


Is it possible to set log scale for a Z axis on a heatmap?

I’ve tried it this way, but Z axis is still linear:

import plotly.graph_objs as go
data = [
        z=[[1, 200, 3000, 500, 1], [20000, 1, 60, 80, 30], [30, 60, 1, -10, 20]],
        x=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
        y=['Morning', 'Afternoon', 'Evening'],
py.offline.iplot(dict(data=data, layout={'scene': {'zaxis': {'type': 'log'}}}))

Any help or direction is much appreciated.

plotly heatmaps only support linear z scales at the moment.

I think logs scales are now possible with python plotly as shown in this plotly example

I stumbled across the example as I am trying to figure out how to do the same but in JavaScript

It’s June 2020, any updates on this? I work with Hi-C datasets, this is really important to visualize this type of data.

Hi @luisdiaz1997 welcome to the forum! For you can pass directly the logarithm of the z value, and customize the ticks of the colorscale to improve its readability. This is explained in these two doc examples (one for plotly express, one for graph_objects)

Hi, I would really like to be able to use log color scale in contour graph object. I can’t open last two links which are potentially useful for that. Can you repost relevant docs? Or suggest another solution? Thank you.

Hi @elizevin

the links should work again. You can set contourplots and heatmaps to logscales BUT you have to customize the colorrange for the data yourself. See the link.

Sadly that is highly impractical and i wont spent my time on writing a class to do that automatically and move back to seaborn.

Nevertheless, thanks guys for plotly and the development! :slight_smile:

As there was still no fix and I eagerly needed a solution, I made this my small weekend project. I used a pandas df and used the column names and index for the x and y names, respectively.

  1. Create a function for the labels.
    You kind of ‘look up’ the logged color value and replace them with the ‘10 to the power of n’ value using the custom colorbar function I made.
def colorbar(n):
    return dict(
        tick0 = 0,
        title = "Log color scale",
        tickmode = "array",
        tickvals = np.linspace(0, n, n+1),
        ticktext = 10**np.linspace(0, n, n+1))
  1. Log transform the data in graph_objects.
    Pay special attention to n here. It takes the log value of the maximum element in your pandas df and rounds it down to an integer. In the colorbar() function, this is used to show the maximum ticktext equaling 10^n. To make sure you see the original data values instead of the logged ones when hovering over, I adjusted the hovertemplate to use the original df value instead of the logged z value.
    n = int(np.round(np.log10(max(df.max(axis=1)))))

    fig = go.Figure(data = go.Heatmap(
        z = np.log10(df),
        x = df.columns,
        y = df.index,
        text = df,
        hovertemplate = "x: %{x} <br>" + "y: %{y} <br>" + "z: %{text}",
        colorbar = colorbar(n+1),
        reversescale = True))

I used a reverse Inferno scale here, but feel free to adjust this. You can play around with the linspace in the colorbar function to show different values, however make sure the ticktext equals 10^tickvals.

I guess this setup is made for a max value of around 10.000.

1 Like