TickBar
Is your feature request related to a problem? Please describe.
When the number of columns or rows of a heatmap are large, it becomes unmanageable to rely on normal text ticks per entry to interpret an explicit or implicit semantic grouping. In addition to group text labels, a colored bar that group the ticks based on a particular groupby column would be helpful.
Example from scanpy groupby:
Describe the solution you'd like
An operation to add an adjoined TickBar.. what I'm calling a single row/column heatmap that encodes a specified groupby feature.
Describe alternatives you've considered
This is conceptually aligned with the planned effort to expand hierarchical ticks to heatmap categorical axes... trying to encode index grouping in an easily parsable way.
Additional context
Minimal example of how to currently achieve this in HoloViews:
import numpy as np
import pandas as pd
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')
categories = {
'Gene_A': 'Group1',
'Gene_B': 'Group1',
'Gene_C': 'Group1',
'Gene_D': 'Group2',
'Gene_E': 'Group2',
'Gene_F': 'Group3',
'Gene_G': 'Group3',
'Gene_H': 'Group3',
'Gene_I': 'Group4',
'Gene_J': 'Group4'
}
genes = list(categories.keys())
samples = [f'Sample_{i}' for i in range(1, 11)]
gene_groups = pd.Series(categories)
group_base_values = {'Group1': 0, 'Group2': 2, 'Group3': -1, 'Group4': 1}
base_values = gene_groups.map(group_base_values).values
expression_matrix = base_values[:, np.newaxis] + np.random.randn(len(genes), len(samples)) * 0.5
index = pd.MultiIndex.from_product([genes, samples], names=['Gene', 'Sample'])
df = pd.DataFrame({'Expression': expression_matrix.ravel()}, index=index).reset_index()
main_heatmap = hv.HeatMap(df, kdims=['Sample', 'Gene'], vdims=['Expression'])
group_to_num = {'Group1': 0, 'Group2': 1, 'Group3': 2, 'Group4': 3}
gene_series = pd.Series(genes)
group_series = gene_series.map(categories)
category_df = pd.DataFrame({
'Gene': genes,
'Category': ' ',
'Group_Name': group_series,
'Group_Num': group_series.map(group_to_num)
})
category_heatmap = hv.HeatMap(
category_df,
kdims=['Category', 'Gene'],
vdims=['Group_Num', 'Group_Name']
)
styled_category = category_heatmap.opts(
cmap='Category10',
width=50,
height=400,
colorbar=False,
xaxis=None,
yaxis=None,
tools=['hover'],
)
styled_main = main_heatmap.opts(
cmap='RdBu_r',
width=600,
height=400,
xlabel='Samples',
tools=['hover'],
xrotation=90,
)
styled_main + styled_category
Having that operation would surely help for this case!
Thinking further: maybe it would make sense to have an easy tool to create a HeatMap/Image from one or more heterogeneous DataFrame columns.
Alternatively/additionally I think the example images for the ComplexHeatmap R package are good for inspiration for what’s possible to add to a heatmap, and therefore a good API for this should be. (I’m not saying that its API itself is an ideal API, just that it has a bunch of possible annotations that could make sense on a heatmap)