Seaborn Heatmap with logarithmic-scale colorbar

前端 未结 4 1967
暗喜
暗喜 2020-12-14 16:19

Is there a way to set the color bar scale to log on a seaborn heat map graph?
I am using a pivot table output from pandas as an input to the call

 sns.he         


        
相关标签:
4条回答
  • 2020-12-14 16:36

    You can normalize the values on the colorbar with matplotlib.colors.LogNorm. I also had to manually set the labels in seaborn and ended up with the following code:

    #!/usr/bin/env python3
    
    import math
    
    import numpy as np
    import seaborn as sn
    from matplotlib.colors import LogNorm
    
    data = np.random.rand(20, 20)
    
    log_norm = LogNorm(vmin=data.min().min(), vmax=data.max().max())
    cbar_ticks = [math.pow(10, i) for i in range(math.floor(math.log10(data.min().min())), 1+math.ceil(math.log10(data.max().max())))]
    
    sn.heatmap(
        data,
        norm=log_norm,
        cbar_kws={"ticks": cbar_ticks}
    )
    

    heatmap rand

    0 讨论(0)
  • 2020-12-14 16:47

    Responding to cphlewis (I don't have enough reputation), I solved this problem using cbar_kws; as I saw here: seaborn clustermap: set colorbar ticks.

    For example cbar_kws={"ticks":[0,1,10,1e2,1e3,1e4,1e5]}.

    from matplotlib.colors import LogNorm
    s=np.random.rand(20,20)
    sns.heatmap(s, norm=LogNorm(s.min(),s.max()),
                cbar_kws={"ticks":[0,1,10,1e2,1e3,1e4,1e5]},
                vmin = 0.001, vmax=10000)
    plt.show()
    

    Have a nice day.

    0 讨论(0)
  • 2020-12-14 16:57

    Short Answer:

    from matplotlib.colors import LogNorm
    
    sns.heatmap(df, norm=LogNorm())
    
    0 讨论(0)
  • 2020-12-14 17:03

    Yes, but seaborn has hard-coded a linear tick locator for the colorbar, so the result might not be quite what you want:

    # http://matplotlib.org/examples/pylab_examples/pcolor_log.html
    # modified to use seaborn
    
    import matplotlib.pyplot as plt
    from matplotlib.colors import LogNorm
    import numpy as np
    from matplotlib.mlab import bivariate_normal
    import seaborn as sns; sns.set()
    
    
    N = 20
    X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
    
    # A low hump with a spike coming out of the top right.
    # Needs to have z/colour axis on a log scale so we see both hump and spike.
    # linear scale only shows the spike.
    Z1 = bivariate_normal(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1 * bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
    
    fig, axs = plt.subplots(ncols=2)
    
    sns.heatmap(Z1, ax = axs[0])
    sns.heatmap(Z1, ax = axs[1],
                #cbar_kws={'ticks':[2,3]}, #Can't specify because seaborn does
                norm=LogNorm(vmin=Z1.min(), vmax=Z1.max()))
    
    
    axs[0].set_title('Linear norm colorbar, seaborn')
    axs[1].set_title('Log norm colorbar, seaborn')
    plt.show()
    

    See the pylab example this started with for a pylab version that automatically gets colorbar tick labels (though is otherwise not as pretty).

    You can edit the seaborn code to make it work: if you alter the plot() function in /seaborn/matrix.py (ver 0.7.0):

        # Possibly add a colorbar
        if self.cbar:
            ticker = mpl.ticker.MaxNLocator(6)
            if 'norm' in kws.keys():
                if type(kws['norm']) is mpl.colors.LogNorm:
                    ticker = mpl.ticker.LogLocator(numticks=8)
    

    you get:

    I'll suggest that on the seaborn github, but if you want it earlier, there it is.

    0 讨论(0)
提交回复
热议问题