Simon Dubois
Simon Dubois

Reputation: 39

Holoviews/Bokeh Radial Heatmap with various cmap

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.

Upvotes: 1

Views: 207

Answers (1)

Simon Dubois
Simon Dubois

Reputation: 39

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

Upvotes: 1

Related Questions