Reverse colormap in matplotlib

前端 未结 7 808
小蘑菇
小蘑菇 2020-11-28 02:04

I would like to know how to simply reverse the color order of a given colormap in order to use it with plot_surface.

7条回答
  •  囚心锁ツ
    2020-11-28 02:52

    As a LinearSegmentedColormaps is based on a dictionary of red, green and blue, it's necessary to reverse each item:

    import matplotlib.pyplot as plt
    import matplotlib as mpl
    def reverse_colourmap(cmap, name = 'my_cmap_r'):
        """
        In: 
        cmap, name 
        Out:
        my_cmap_r
    
        Explanation:
        t[0] goes from 0 to 1
        row i:   x  y0  y1 -> t[0] t[1] t[2]
                       /
                      /
        row i+1: x  y0  y1 -> t[n] t[1] t[2]
    
        so the inverse should do the same:
        row i+1: x  y1  y0 -> 1-t[0] t[2] t[1]
                       /
                      /
        row i:   x  y1  y0 -> 1-t[n] t[2] t[1]
        """        
        reverse = []
        k = []   
    
        for key in cmap._segmentdata:    
            k.append(key)
            channel = cmap._segmentdata[key]
            data = []
    
            for t in channel:                    
                data.append((1-t[0],t[2],t[1]))            
            reverse.append(sorted(data))    
    
        LinearL = dict(zip(k,reverse))
        my_cmap_r = mpl.colors.LinearSegmentedColormap(name, LinearL) 
        return my_cmap_r
    

    See that it works:

    my_cmap        
    
    
    my_cmap_r = reverse_colourmap(my_cmap)
    
    fig = plt.figure(figsize=(8, 2))
    ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
    ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
    norm = mpl.colors.Normalize(vmin=0, vmax=1)
    cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = my_cmap, norm=norm,orientation='horizontal')
    cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = my_cmap_r, norm=norm, orientation='horizontal')
    

    EDIT


    I don't get the comment of user3445587. It works fine on the rainbow colormap:

    cmap = mpl.cm.jet
    cmap_r = reverse_colourmap(cmap)
    
    fig = plt.figure(figsize=(8, 2))
    ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
    ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
    norm = mpl.colors.Normalize(vmin=0, vmax=1)
    cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = cmap, norm=norm,orientation='horizontal')
    cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = cmap_r, norm=norm, orientation='horizontal')
    

    But it especially works nice for custom declared colormaps, as there is not a default _r for custom declared colormaps. Following example taken from http://matplotlib.org/examples/pylab_examples/custom_cmap.html:

    cdict1 = {'red':   ((0.0, 0.0, 0.0),
                       (0.5, 0.0, 0.1),
                       (1.0, 1.0, 1.0)),
    
             'green': ((0.0, 0.0, 0.0),
                       (1.0, 0.0, 0.0)),
    
             'blue':  ((0.0, 0.0, 1.0),
                       (0.5, 0.1, 0.0),
                       (1.0, 0.0, 0.0))
             }
    
    blue_red1 = mpl.colors.LinearSegmentedColormap('BlueRed1', cdict1)
    blue_red1_r = reverse_colourmap(blue_red1)
    
    fig = plt.figure(figsize=(8, 2))
    ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
    ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
    
    norm = mpl.colors.Normalize(vmin=0, vmax=1)
    cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = blue_red1, norm=norm,orientation='horizontal')
    cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = blue_red1_r, norm=norm, orientation='horizontal')
    

提交回复
热议问题