0

I'm creating a colorbar with the function make_colormap. Source: Create own colormap using matplotlib and plot color scale. Also i'm plotting many maps with for month, data in normals.groupby('MONTH'): I want to create a color bar with the same values for the same colors (to be able to compare values in maps) but in the:

rvb = make_colormap(
    [c('brown'), c('orange'), 0.10, c('orange'), c('yellow'), 0.20, c('green'), c('cyan'), 0.66, c('blue'), c('purple') ])

I can only put percentages. Do you know how can i modify this to put exact values instead of percentages?

import matplotlib.colors as mcolors

def make_colormap(seq):
    """Return a LinearSegmentedColormap
    seq: a sequence of floats and RGB-tuples. The floats should be increasing
    and in the interval (0,1).
    """
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
    cdict = {'red': [], 'green': [], 'blue': []}
    for i, item in enumerate(seq):
        if isinstance(item, float):
            r1, g1, b1 = seq[i - 1]
            r2, g2, b2 = seq[i + 1]
            cdict['red'].append([item, r1, r2])
            cdict['green'].append([item, g1, g2])
            cdict['blue'].append([item, b1, b2])
    return mcolors.LinearSegmentedColormap('CustomMap', cdict)

c = mcolors.ColorConverter().to_rgb
rvb = make_colormap(
    [c('brown'), c('orange'), 0.10, c('orange'), c('yellow'), 0.20, c('green'), c('cyan'), 0.66, c('blue'), c('purple') ])

for month, data in normals.groupby('MONTH'):
    
    lons, lats= np.array(data['LONGITUDE']), np.array(data['LATITUDE'])
    ppvalues=np.array(data['PP']).astype(int)
    
    month = data['MONTH'].iloc[0]
    fig = plt.figure('map', figsize=(7,7), dpi=200)
    ax = fig.add_axes([0.1, 0.12, 0.80, 0.75], projection=ccrs.PlateCarree())
    plt.xlabel('LONGITUDE') 
    plt.ylabel('LATITUDE') 
    
    ax.outline_patch.set_linewidth(0.3)
    
    l = NaturalEarthFeature(category='cultural', name='admin_0_countries', scale='50m', facecolor='none')
    ax.add_feature(l, edgecolor='black', linewidth=0.25)
    
    img = ax.scatter(lons, lats, s=7, c=ppvalores, cmap=rvb,
                     marker='o', transform=ccrs.PlateCarree())
    
    #ticks=[0,1,2,3,4,5,6,7,8,9,10]
    cb = plt.colorbar(img, extend='both',
                        spacing='proportional', orientation='horizontal',
                        cax=fig.add_axes([0.12, 0.12, 0.76, 0.02]))
    plt.show()
    fig.savefig("path/".png")

I'm relatively new in python so would you mind to help me?

Thanks in advance.

Javier
  • 493
  • 3
  • 15

1 Answers1

2

You could apply a norm. Using the same norm for all plots would make the colors consistent. It is unclear what the range of your data['PP'] column is. Here is an example of the changes if you would like 100, 200 and 660 for the three values in the list given to make_colormap:

vmin = data['PP'].min() # the overall minimum
vmax = data['PP'].max() # the overall maximum
norm = plt.Normalize(vmin, vmax) # function that maps the range of data['PP'] to the range [0,1]

rvb = make_colormap(
    [c('brown'), c('orange'), norm(100), c('orange'), c('yellow'), norm(200), c('green'), c('cyan'), norm(660), c('blue'), c('purple')])

for month, data in normals.groupby('MONTH'):
    ...
    img = ax.scatter(..., cmap=rvb, norm=norm)
    ...
JohanC
  • 71,591
  • 8
  • 33
  • 66