python - How to display a colorbar with custom normalized colormap? - Stack Overflow

I've plotted a scatter with custom colormap's normalization. Scatter appears right. After tha

I've plotted a scatter with custom colormap's normalization. Scatter appears right. After that, I've added a colorbar and I want the colors on this colorbar will be same as on the scatter. There is my code:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl

class SigmoidNormalize(mpl.colors.Normalize):
    def __init__(self, vmin=None, vmax=None, vcenter=None, clip=False):
        if vcenter is None:
            self.vcenter = (vmax+vmin) / 2
        self.vcenter = vcenter
        super().__init__(vmin, vmax, clip)

    def __call__(self, value, clip=None):
        threshold = self.vcenter
        value = (value - threshold) * 10
        norm = 1 / (1+np.exp(-value))
        return norm
        

    def inverse(self, value):
        threshold = self.vcenter
        nonzero = np.logical_and(value != 0, value != 1)
        norm = np.empty_like(value)
        norm[nonzero] = -np.log(1/value[nonzero] - 1)
        norm[nonzero] = norm[nonzero] / 10 + threshold
        norm[value==0] = self.vmin
        norm[value==1] = self.vmax
        return norm

class SigmoidNormalize_r(SigmoidNormalize):
    def __init__(self, vmin=None, vmax=None, vcenter=None, clip=False):
        super().__init__(vmin, vmax, vcenter, clip)
    
    def __call__(self, value, clip=None):
        return super().inverse(value)
        
    def inverse(self, value):
        return super().__call__(value)

def plot_predictions(predictions, 
                     actual, 
                     threshold=0.5, 
                     threshold_gap=0.1):
    fig = plt.figure()
    ax = fig.add_subplot()
    normals = np.where(np.logical_and(actual == 0, predictions < threshold))[0]
    abnormals = np.where(np.logical_and(actual == 1, predictions >= threshold))[0]
    normals_wrong = np.where(np.logical_and(actual == 0, predictions > threshold))[0]
    abnormals_wrong = np.where(np.logical_and(actual == 1, predictions <= threshold))[0]
    
    cmap = mpl.cm.rainbow
    norm = SigmoidNormalize(vmin=0, vmax=1, vcenter=threshold-threshold_gap)
    norm_r = SigmoidNormalize_r(vmin=0, vmax=1, vcenter=threshold-threshold_gap)
    # Artist's zorder is just a scalar and cannot be applied to
    # each point in scatter, so we need to draw right and wrong
    # predictions separately, to place wrong predictions on the top
    # and make it's visibility more clean.
    ax.scatter(predictions[normals], normals, 
               c=predictions[normals],
               norm=norm,
               cmap=cmap)
    ax.scatter(predictions[abnormals], abnormals, 
               c=1-predictions[abnormals],
               norm=norm,
               cmap=cmap)
    ax.scatter(predictions[normals_wrong], normals_wrong, 
               c=predictions[normals_wrong],
               norm=norm,
               cmap=cmap)
    ax.scatter(predictions[abnormals_wrong], abnormals_wrong, 
               c=1-predictions[abnormals_wrong],
               norm=norm,
               cmap=cmap)
    
    ax.axvline(threshold, color='red', linestyle='--', linewidth=1)
    ax.set_xlim((0, 1))
    fig.colorbar(mpl.cm.ScalarMappable(norm=norm_r, cmap=cmap), ax=ax,
                 orientation='horizontal')

if __name__ == '__main__':
    predictions1 = np.abs(np.random.normal(0, 0.25, 1000))
    predictions2 = 1-np.abs(np.random.normal(0, 0.25, 1000))
    actual1 = np.full_like(predictions1, 0)
    actual2 = np.full_like(predictions2, 1)
    predictions = np.concatenate((predictions1, predictions2))
    actual = np.concatenate((actual1, actual2))
    gen = np.random.Generator(np.random.MT19937())
    con = np.array([predictions, actual])
    gen.shuffle(con, axis=1)
    predictions, actual = con
    plot_predictions(predictions, actual)

There is what I've got:

The greater the difference between predictions and actuals, the closer the color is to red. On the plot we can see that at the center of the graph the points are orange, while on the colorbar they are green. We need to adjust the colorbar so that it also has orange in the middle and red on the right side. The labels should be uniform, but if this is not possible, just remove them.

There is what I want:

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742294357a4416814.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信