简体   繁体   中英

How to create a custom diverging colormap in matplotlib?

I want to create a colormap similar to "RdBu" in matplotlib. 传统的“RdBu”

I want to make the colormap in this sequence light blue->dark blue-> black(center)->dark red->light red. Something like this. 所需的颜色图

So it is similar to "RdBu" but white changes to black & dark colors interchanged with light colors. So it is just inverting the "RdBu" colors. I don't know how to do it.

I just tried to create a colormap to meet my requirements recently. Here is my attempt to build the colormap you need. I know it is not perfect. But it show you how to get started.

import matplotlib
import matplotlib.cm as cm
from matplotlib.colors import Normalize
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# create sample data set
# both will be: 0 - 1
x = np.random.rand(400)
y = np.random.rand(400)
# for realistic use
# set extreme values -900, +900 (approx.)
rval = 900
z = ((x+y)-1)*rval

# set up fig/ax for plotting
fig, ax = plt.subplots(figsize=(5, 5))

# option: set background color
ax.set_facecolor('silver')

# the colormap to create
low2hiColor = None

# create listedColormap
bottom = cm.get_cmap('Blues', 256)
top = cm.get_cmap('Reds_r', 256)
mycolormap = np.vstack((bottom(np.linspace(0.25, 1, 64)),
                        np.array([
                        [0.03137255, 0.08823529, 0.41960784, 1.],
                        [0.02137255, 0.04823529, 0.21960784, 1.],
                        [0.01137255, 0.02823529, 0.11960784, 1.],
                        [0.00037255, 0.00823529, 0.00960784, 1.],
                        #[0.00000255, 0.00000529, 0.00060784, 1.],
                        ])
                       ))
mycolormap = np.vstack((mycolormap,
                        np.array([
                        #[0.00060784, 0.00000529, 0.00000255, 1.],
                        [0.00960784, 0.00823529, 0.00037255, 1.],
                        [0.11960784, 0.02823529, 0.01137255, 1.],
                        [0.21960784, 0.04823529, 0.02137255, 1.],
                        [0.41960784, 0.08823529, 0.03137255, 1.],
                        ])
                       ))
mycolormap = np.vstack((mycolormap,
                        top(np.linspace(0, 0.75, 64)),
                       ))

low2hiColor = ListedColormap(mycolormap, name='low2hiColor')

# colorbar is created separately using pre-determined `cmap`
minz = -900 #min(z)
maxz = 900  #max(z)
norm_low2hiColor = matplotlib.colors.Normalize(minz, maxz)

# plot dataset as filled contour
norm1 = matplotlib.colors.Normalize(minz, maxz)
cntr1 = ax.tricontourf(x, y, z, levels=64, cmap=low2hiColor, norm=norm1)

gridlines = ax.grid(b=True)  # this plot grid

cbar= plt.colorbar( cntr1 ) 
plt.title("Light-Dark Blue Black Dark-Light Red")
plt.show()

The sample plot:

b-k-r

I wanted to create diverging colormaps by simply combining existing ones.

Here's the code:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import colors
from typing import List, Tuple

def get_hex_col(cmap) -> List[str]:
    """Return list of hex colors for cmap"""
    return [colors.rgb2hex(cmap(i)) for i in range(cmap.N)]

def get_cmap_list(
        cmap_name: str, length_n: int) -> [str]:
    """Create a classified colormap of length N
    """
    cmap = plt.cm.get_cmap(cmap_name, length_n)
    cmap_list = get_hex_col(cmap)
    return cmap_list

def get_diverging_colormap(
        cmap_diverging:Tuple[str,str], color_count: int = k_classes):
    """Create a diverging colormap from two existing with k classes"""
    div_cmaps: List[List[str]] = []
    for cmap_name in cmap_diverging:
        cmap_list = get_cmap_list(
            cmap_name, length_n=color_count)
        div_cmaps.append(cmap_list)
    div_cmaps[1] = list(reversed(div_cmaps[1]))
    cmap_nodata_list = div_cmaps[1] + div_cmaps[0]
    return colors.ListedColormap(cmap_nodata_list)

# apply
cmaps_diverging: Tuple[str] = ("OrRd", "Purples")
cmap = get_diverging_colormap(cmaps_diverging)

# visualize
def display_hex_colors(hex_colors: List[str]):
    """Visualize a list of hex colors using pandas"""
    df = pd.DataFrame(hex_colors).T
    df.columns = hex_colors
    df.iloc[0,0:len(hex_colors)] = ""
    display(df.style.apply(lambda x: apply_formatting(x, hex_colors)))

display_hex_colors(cmap.colors)

Output for example "OrRd" and "Purples": 在此处输入图像描述

I made a simple tool that helps to create colormaps and generates the required code:

https://eltos.github.io/gradient/#4C71FF-0025B3-000000-C7030D-FC4A53

Screenshot

-->

And the code you get from the download button:

 #!/usr/bin/env python from matplotlib.colors import LinearSegmentedColormap my_gradient = LinearSegmentedColormap.from_list('my_gradient', ( # Edit this gradient at https://eltos.github.io/gradient/#4C71FF-0025B3-000000-C7030D-FC4A53 (0.000, (0.298, 0.443, 1.000)), (0.250, (0.000, 0.145, 0.702)), (0.500, (0.000, 0.000, 0.000)), (0.750, (0.780, 0.012, 0.051)), (1.000, (0.988, 0.290, 0.325)))) if __name__ == '__main__': import numpy as np from matplotlib import pyplot as plt plt.imshow([np.arange(1000)], aspect="auto", cmap=my_gradient) plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM