sk3145
sk3145

Reputation: 174

Matplotlib: How to change colorbar gradient using user input

I want to customize the colorbar(colormap) with specific value range. The color range should varies with the given parameter (Tup,Tmd,Tbt) where

Mid color (lime) should range through user selected Tup and Tbt with Tmd as a mid-point.

enter image description here

I tried to generate custom colormap using below code snippet, but could not able to control its range using user provided values.

cmap = LinearSegmentedColormap.from_list("", ["blue","gray","lime","gray","red"])
cax = ax.pcolor(data,cmap=cmap,edgecolors='k',vmin=0,vmax=100)

How to control colormap values depending on user input?

Upvotes: 0

Views: 828

Answers (1)

Diziet Asahi
Diziet Asahi

Reputation: 40667

You can use a combination of LinearSegmentedColormap to create the colormap, and DiverginNorm to define the end- and center-points.

Demonstration (code is not optimized, but it shows the general idea):

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
from matplotlib import colors

maxV = 100
minV = -100
centerV = -50
N=10
data = np.random.uniform(low=minV, high=maxV, size=(N,N))
cmap = colors.LinearSegmentedColormap.from_list('', ['blue','lime','red'])
norm = colors.DivergingNorm(vmin=minV, vcenter=centerV, vmax=maxV)


fig, (ax, axSlide1, axSlide2, axSlide3) = plt.subplots(4,1, gridspec_kw=dict(height_ratios=[100,5,5,5]))
im = ax.imshow(data, cmap=cmap, norm=norm)
cbar = fig.colorbar(im, ax=ax)


axcolor = 'lightgoldenrodyellow'
for sax in [axSlide1, axSlide2, axSlide3]:
    sax.set_facecolor(axcolor)

smin = Slider(axSlide1, 'min', minV, maxV, valinit=minV)
scenter = Slider(axSlide2, 'center', minV, maxV, valinit=centerV)
smax = Slider(axSlide3, 'max', minV, maxV, valinit=maxV)



def update(val):
    global cbar
    minV = smin.val
    maxV = smax.val
    centerV = scenter.val
    if minV>maxV:
        minV=maxV
        smin.set_val(minV)
    if maxV<minV:
        maxV=minV
        smax.set_val(maxV)
    if centerV<minV:
        centerV = minV
        scenter.set_val(centerV)
    if centerV>maxV:
        centerV = maxV
        scenter.set_val(centerV)

    #redraw with new normalization
    norm = colors.DivergingNorm(vmin=minV, vcenter=centerV, vmax=maxV)
    ax.cla()
    cbar.ax.cla()
    im = ax.imshow(data, cmap=cmap, norm=norm)
    cbar = fig.colorbar(im, cax=cbar.ax)
    fig.canvas.draw_idle()


smin.on_changed(update)
smax.on_changed(update)
scenter.on_changed(update)

plt.show()

enter image description here

Upvotes: 2

Related Questions