4
votes

I have a simple dataframe with columns and rows that I want to visualize using hvpolot.heatmap. I can do something pretty similar with:

df.style.background_gradient(cmap='summer')

.. in Jupyter, looks like: enter image description here

The dataframe is pretty simple:

> df.index
Index(['ackerland', 'friedhof', 'gartenland', 'gehoelz', 'golfplatz',
       'gruenland', 'heide', 'kleingarten', 'laubholz', 'mischholz', 'moor',
       'nadelholz'],
      dtype='object')
> df.columns
Index(['hiking', 'biking', 'walking', 'sport', 'friends', 'family', 'picnic'], dtype='object')

But when I do:

>import hvplot.pandas
>df.hvplot.heatmap(colorbar=True)
ValueError: Dimensions must be defined as a tuple, string, dictionary or Dimension instance, found a NoneType type.```

This does also not work:

>df.hvplot.heatmap(x=df.index, y=df.columns, colorbar=True)
ValueError: The truth value of a Index is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

I've read most docs regarding this, but still don't fully understand how to specify value dimensions for pandas dataframe in hvplot/holoviews/bokeh:

[edit] Added feature request

2
I even found out how to plot this in holoviews: hv.HeatMap({'x': df.columns, 'y':df.index, 'z': df}, ['x', 'y'], 'z') but the same syntax does not work in hvplotAlex
Thanks Alex, could you file an issue to ask us to support this in hvplot?philippjfr
Thanks philippjfr! Sure, I'll report it asap (also, sorry for asking twice - you already explained to me once how to specify value dimensions, I am embarrassing aware of this)Alex

2 Answers

6
votes

1) If your data is in the wide format that you have, with categories as index, and columns as values, like this:

+--------------------------+
|         colA  colB  colC |
+--------------------------+
| group1    10 5.000 1.200 |
| group2    12 3.000 4.500 |
| group3    14 1.200 2.300 |
+--------------------------+

Then you just do df.heatmap.hvplot() with hvplot >= 0.5:

import pandas as pd
import holoviews as hv
import hvplot.pandas
hv.extension('bokeh')

df = pd.DataFrame({
    'colA': [10, 12, 14],
    'colB': [5, 3.0, 1.2],
    'colC': [1.2, 4.5, 2.3]},
    index=['group1', 'group2', 'group3'],
)

df.hvplot.heatmap()

If you would like to add data labels to the heatmap you can do:

heatmap = df.hvplot.heatmap()

heatmap * hv.Labels(heatmap)



2) However when your data is like this where groups are just another column and not the index:

+------------------------------+
|      group colA  colB  colC  |
+------------------------------+
| 1   group1    10 5.000 1.200 |
| 2   group2    12 3.000 4.500 |
| 3   group3    14 1.200 2.300 |
+------------------------------+

Then you could either set your group as your index with df.set_index('group') (and apply solution 1), or melt your data into a long format:

df_melt = df.melt(id_vars='group')

After melting your data looks like this:

+---+--------+----------+--------+
|   | group  | variable | value  |
+---+--------+----------+--------+
| 0 | group1 | colA     | 10.000 |
| 1 | group2 | colA     | 12.000 |
| 2 | group3 | colA     | 14.000 |
| 3 | group1 | colB     | 5.000  |
| 4 | group2 | colB     | 3.000  |
+---+--------+----------+--------+

This melted data is in the format where you can use the x and y and C keywords:

df_melt.hvplot.heatmap(x='group', y='variable', C='value')

Or you can use that melted (long) data to create the heatmap in HoloViews:

hv.HeatMap(df_melt, kdims=['group', 'variable'], vdims=['value'])

The advantage of melted data is that you can now also easily add data labels to your heatmap:

heatmap = df_melt.hvplot.heatmap(x='group', y='variable', C='value')
labels = hv.Labels(data=df_melt, kdims=['group', 'variable'], vdims=['value'])

heatmap * labels

Another (even) easier way to add data labels / values to your heatmap is like this:

heatmap = df_melt.hvplot.heatmap(x='group', y='variable', C='value')
heatmap * hv.Labels(heatmap)



Resulting plot:

nice heatmap with labels using hvplot or holoviews

More info on heatmaps in hvplot:
https://hvplot.holoviz.org/reference/pandas/heatmap.html

More info on heatmaps in holoviews:
https://holoviews.org/reference/elements/bokeh/HeatMap.html

More info on (data) labels in holoviews:
https://holoviews.org/reference/elements/bokeh/Labels.html

1
votes

For what you want, you can do :

df.hvplot.heatmap(x='index', y='columns', colorbar=True)