10

I have a series of values that varies between -180 to 180, I what a color map symmetric around zero, i.e. the color for -180 is the same for 180 values and so on. It is my first time using matplotlib I only don't find the way to make it symmetric around zero, the negatives always have different colors that the positives. Thank you very much.

AJaramillo
  • 400
  • 5
  • 18
  • please post the relevant code where you fail to do so – gg349 Feb 10 '15 at 18:44
  • You could define a custom colormap: see http://stackoverflow.com/q/24997926/190597 or http://stackoverflow.com/q/16834861/190597, for example. – unutbu Feb 10 '15 at 19:00
  • Thank you, I guess it is the only way to do it because there is not a predefined colormap for that. – AJaramillo Feb 10 '15 at 19:02
  • Right, there is no [predefined colormap](http://wiki.scipy.org/Cookbook/Matplotlib/Show_colormaps) which is symmetric. – unutbu Feb 10 '15 at 19:27
  • 1
    You could also plot the absolute values of your data and use a normal sequential colormap. – mwaskom Feb 10 '15 at 21:04
  • 1
    See http://stackoverflow.com/questions/15399095/stacking-colormaps/15399564#15399564 – tacaswell Feb 11 '15 at 04:52

2 Answers2

5

Thanks to the contribution from : https://stackoverflow.com/a/31052741

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors


def symmetrical_colormap(cmap_settings, new_name = None ):
    ''' This function take a colormap and create a new one, as the concatenation of itself by a symmetrical fold.
    '''
    # get the colormap
    cmap = plt.cm.get_cmap(*cmap_settings)
    if not new_name:
        new_name = "sym_"+cmap_settings[0]  # ex: 'sym_Blues'
    
    # this defined the roughness of the colormap, 128 fine
    n= 128 
    
    # get the list of color from colormap
    colors_r = cmap(np.linspace(0, 1, n))    # take the standard colormap # 'right-part'
    colors_l = colors_r[::-1]                # take the first list of color and flip the order # "left-part"

    # combine them and build a new colormap
    colors = np.vstack((colors_l, colors_r))
    mymap = mcolors.LinearSegmentedColormap.from_list(new_name, colors)

    return mymap

And testing it gives you :

# --- Quick test -------------------------
cmap_settings = ('Blues', None)  # provide int instead of None to "discretize/bin" the colormap
mymap = symmetrical_colormap(cmap_settings= cmap_settings, new_name =None )

data = np.random.rand(10,10) * 2 - 1
plt.pcolor(data, cmap=mymap)
plt.colorbar()
plt.show()

Result_figure

GentilsTo
  • 101
  • 2
  • 4
1

Not perfect, but the Diverging colormaps are at least centered:

from matplotlib import pyplot as plt
<function using cmap>.(cmap=plt.get_cmap("PiYG"))

cmaps examples

Sylvain
  • 679
  • 9
  • 13