0

Just wondering how I can create a custom colour scheme based on conditions for a holoviews heatmap. I have created a column for colours that are based on conditions within the data. However, when I plot these the standard cmap appears but my colour scheme appears on the cells when I hover over them. Does anyone know how I can ignore the standard color map that is displaying or implement it so my conditional one appears instead. Example code below:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from datetime import datetime
import holoviews as hv
from holoviews import opts
import panel as pn
from bokeh.resources import INLINE
from holoviews import dim
hv.extension('bokeh', 'matplotlib')
gv.extension('bokeh')

pd.options.plotting.backend = 'holoviews'

green = '#00FF00'
amber = '#FFFF00'
red = '#FF0000'

Data = [['A', 'Foo', 0.2] , ['B', 'Bar', 0.9], ['C', 'Cat', 0.7]]
df = pd.DataFrame(Data, columns = ['Name', 'Category', 'Value'])

df['colors'] = df.apply(lambda row: green if row['Value'] >= 0.9 else
                                    amber if row['Value'] < 0.9 and row['Value'] >= 0.7 else
                                    red if row['Value'] < 0.7 else '#8A2BE2', axis = 1)



df_hm = hv.HeatMap(df,kdims=['Category','Name'], vdims=['Value', 'colors']).opts(width=900, height=400, color = hv.dim('colors'),  tools=['hover'])

When this code is ran I get the following, which is the standard cmap: enter image description here

However, when I hover over the cell the color changes to scheme I want, unfortunatly I can't add a picture to show it. But does anyone know how I can make it only show the conditional colouring that I am after.

I've added a picutre of what is happening. When I hover over the cell you can see the conditonal coloring, however there is cmap color overlayed on to this, which I want to remove.

Current behavior

Thanks a bunch for any help!

Amen_1990
  • 51
  • 5

1 Answers1

0

You are using the wrong keyword in your ops() call. You have to use cmap instead of color.

Here is a very basic example, adapted from here.

import holoviews as hv
from holoviews import opts
hv.extension('bokeh')

factors = ["a", "b", "c", "d", "e", "f", "g", "h"]
x =  [50, 40, 65, 10, 25, 37, 80, 60]
scatter = hv.Scatter((factors, x))
spikes = hv.Spikes(scatter)

x = ["foo", "foo", "foo", "bar", "bar", "bar", "baz", "baz", "baz"]
y = ["foo", "bar", "baz", "foo", "bar", "baz", "foo", "bar", "baz"]
z = [0, 1, 2, 3, 4, 5, 6, 7, 8]
colors = ['#00FF00','#FFFF00','#FF0000','#FFFF00','#FF0000', '#00FF00','#FF0000', '#00FF00','#FFFF00']

hv.HeatMap((x,y,z)).opts(width=450, height=400, cmap=colors,  tools=['hover'])

Output

HeatMap with user defined colors.

mosc9575
  • 5,618
  • 2
  • 9
  • 32
  • Hi There! Thank you for the reply and suggestion! I guess my only issue with this workaround is that my colouring is conditional, so it might change depending on new data. So in this method I'd need to correct the order of the colours in the cmap to take that into account. Is there no way to make the cmap conditional based on the underlying data? Like the colours are all there when I use "colors" but unfortuantely they only appear once I hover over the cell. – Amen_1990 Apr 22 '22 at 09:05
  • I've added a picutre about what is happening. – Amen_1990 Apr 22 '22 at 09:18
  • Your condition is outside of the plot. Did you try `cmap=df['colors']`? I guess this should work. – mosc9575 Apr 22 '22 at 11:52
  • so cmap in holoview doesnt accept a list. So I turned the color colomn into a list but it seems to have the correct colors but it is following some random order rather than the order of the list. :( 'cmap1 = list(df['colors']) opts(cmap = cmap1)' – Amen_1990 Apr 22 '22 at 12:09
  • *only accepts a list – Amen_1990 Apr 22 '22 at 12:15