1

So I have created a radial HeatMap with Holoviews & Bokeh, but for the moment it uses a single cmap (left) and I would like to apply different cmap (right, modified with Gimp). Is there a way to do so ?

Single cmap vs various cmap

(Radial HeatMap based on https://holoviews.org/reference/elements/bokeh/RadialHeatMap.html)

Thanks !

EDIT :

Initial code:

def hook(p, _):
    p.state.xgrid.grid_line_color = None
    p.state.ygrid.grid_line_color = None
    p.state.axis.visible = False
    p.state.outline_line_color = None


heatmap = hv.HeatMap(df, ["Criterion", "Factor"])
heatmap.opts(opts.HeatMap(radial=True, width=800, height=800, cmap='cwr', tools=["hover"], hooks=[hook], xmarks=[sum([len(d.criteria) for d in data[:i]]) for i in range(len(data))], ymarks=0, xticks=None, yticks=None))

Modified code to generate partial heatmaps :

def hook(p, _):
    p.state.xgrid.grid_line_color = None
    p.state.ygrid.grid_line_color = None
    p.state.axis.visible = False
    p.state.outline_line_color = None


all_heatmaps = None
for d in data:
    sub_df = df.copy()
    sub_df.loc[~df['Criterion'].isin(d.criteria), 'Value'] = np.nan
    heatmap = hv.HeatMap(sub_df, ["Criterion", "Factor"])
    heatmap.opts(opts.HeatMap(radial=True, width=800, height=800, cmap=d.cmap, tools=["hover"], hooks=[hook], xmarks=[sum([len(d.criteria) for d in data[:i]]) for i in range(len(data))], ymarks=0, xticks=None, yticks=None))
    all_heatmaps = all_heatmaps * heatmap if all_heatmaps else heatmap

Result :

Partial heatmaps

We only see the outlines of the heatmaps underneath the last one.

  • Maybe if you overlay 3 partial heatmaps, each with its own colormap? – James A. Bednar Jan 10 '22 at 19:33
  • I can't find any parameter to specify the angular range of the HeatMap. I tried overlaying 3 heatmaps and setting unwanted values to numpy.nan hoping for those values to not be displayed but they are in fact displayed in white, so they mask the heatmaps underneath (cf. EDIT). – Simon Dubois Jan 11 '22 at 08:59

1 Answers1

1

After insisting (following @James comment) I found how to overlay HeatMaps whithout masking the ones underneath. So I had to overlay N+1 HeatMaps :

  • N for the color maps (with clipping_colors={'NaN':'#00000000'} to enable transparency)
  • 1 last one completly transparent (cmap=['#00000000']) to manage the tooltips with all the numeric data (tools=['hover']).

Here is the code :

# Set options common to all HeatMaps
opts.defaults(opts.HeatMap(radial=True, width=800, height=800, hooks=[hook], xmarks=[sum([len(d.criteria) for d in data[:i]]) for i in range(len(data))], ymarks=0, xticks=None, yticks=None))
all_heatmaps = None
# Loop through data (a cmap for each data set)
for d in data:
    # Copy global df and only keep values from this data set
    sub_df = df.copy()
    sub_df.loc[~df['Criterion'].isin(d.criteria), 'Value'] = np.nan
    # Create heatmap with cmap from this data set (set all NaN values to transparent)
    heatmap = hv.HeatMap(sub_df, ["Criterion", "Factor"])
    heatmap.opts(opts.HeatMap(cmap=d.cmap, clipping_colors={"NaN": '#00000000'}))
    all_heatmaps = all_heatmaps * heatmap if all_heatmaps else heatmap

# Create final HeatMap fully transparent to manage data tooltips
heatmap = hv.HeatMap(df, ["Criterion", "Factor"])
heatmap.opts(opts.HeatMap(cmap=['#00000000'], tools=['hover']))
all_heatmaps *= heatmap

enter image description here