Black Lives Matter. Please consider donating to Black Girls Code today.

Use heatmap colorscale to set colors in another plot/Get color corresponding to a value from colorscale

I have a heatmap showing correlations which uses a custom colorscale. Now, I want to plot a line graph with multiple lines, each with the color corresponding to a particular z value from the heatmap.

How do I extract the rgb() code corresponding to a particular value, given that the colorscale is fixed and the range of values are also fixed (in [-1,1])?

@muser There is no function that returns the corresponding color of a value, val, in [vmin, vmax], given val, vmin, vmax and a Plotly colorscale, but it is not complicated to devise one, following the following steps:

  1. given a colorscale, let us say:

pl_scl=[[0.0, 'rgb(0,0,0)'], [0.1, 'rgb(16,41,119)'], [0.2, 'rgb(33,94,123)'], [0.3, 'rgb(49,130,122)'], [0.4, 'rgb(62,145,90)'], [0.5, 'rgb(93,160,75)'], [0.6, 'rgb(141,171,86)'], [0.7, 'rgb(183,181,94)'], [0.8, 'rgb(195,164,110)'], [0.9, 'rgb(225,191,175)'], [1.0, 'rgb(253,250,250)']]

extract the plotly_scale=[0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
and the
plotly_colors=['rgb(0,0,0)', 'rgb(16,41,119)', 'rgb(33,94,123)', 'rgb(49,130,122)', 'rgb(62,145,90)', 'rgb(93,160,75)', 'rgb(141,171,86)', 'rgb(183,181,94)', 'rgb(195,164,110)', 'rgb(225,191,175)', 'rgb(253,250,250)']

as follows:

 plotly_scale, plotly_colors=map(float, np.array(pl_scl)[:,0]), np.array(pl_scl)[:,1]
  1. Extract from the list plotly_colors the list of tuples, convert it to a numpy.array and divide that array by 255.0
    to get the mpl_colormap=np.array([[ 0. , 0. , 0. ], [ 0.0627451 , 0.16078431, 0.46666667], [ 0.12941176, 0.36862745, 0.48235294], [ 0.19215686, 0.50980392, 0.47843137], [ 0.24313725, 0.56862745, 0.35294118], [ 0.36470588, 0.62745098, 0.29411765], [ 0.55294118, 0.67058824, 0.3372549 ], [ 0.71764706, 0.70980392, 0.36862745], [ 0.76470588, 0.64313725, 0.43137255], [ 0.88235294, 0.74901961, 0.68627451], [ 0.99215686, 0.98039216, 0.98039216]])

For example these two lines of code perform these operations:

  from ast import literal_eval
  mpl_colormap=np.array(map(literal_eval,[color[3:] for color in plotly_colors] ))/255.0
  1. define a function get_color_for_val(val, plotly_scale, mpl_colormap, vmin, vmax) that returns the
    color corresponding to the value val from the interval [vmin, vmax] (in your case in vmin=-1, vmax=1).

Namely:

  • normalize val, i.e. compute v=(val-vmin)/(vmax-vmin)

  • By a sequential search or a binary search find two consecutive indices idx, idx+1 of elements in plotly_scale
    such that v belongs to the interval [plotly_scale[idx], plotly_scale[idx+1];

  • normalize v: v_normalized=(v-plotly_scale[idx])/(plotly_scale[idx+1]-plotly_scale[idx])

  • get by linear interpolation the the color corresponding to v_normalized, that belongs to the “interval” of colors [mpl_colormap[idx], mpl_colormap[ix+1]]:

    val_color01=mpl_colormap[idx]+v_normalized*(mpl_colormap[idx + 1]-mpl_colormap[idx])
    

val_color01 is the corresponding rgb color of the initial value val, with r,g,b, in [0,1];

  • convert the val_colors01 to a color with r, g, b in [0,255]; let us call the resulted array of shape (3,) val_colors_0255;

  • return the string 'rgb(val_colors_0255[0], val_colors_0255[1], val_colors_0255[2])'; this is the plotly color code corresponding to val