Black Lives Matter. Please consider donating to Black Girls Code today. # Heatmaps with multicolor cells

Hi,

I am trying to plot the occurrence of some predefined events (say A, B, C) throughout the year using a “calendar heatmap”, similar to that proposed in Colored calendar heatmap in dash.
Problem is, on a given day multiple events may occur. I would like to plot the different combinations (A+B, B+C, A+B+C, …) by splitting the associated heatmap cells in halves (or thirds) and color them with the labels’ colors.

This figure depicts an example: What would be the best way to achieve this? I’ve considered different options but they all come with shortcomings:

1. Use a datatable and then perform conditional style formatting of the cells with linear gradients. However, this then prevents me from using hover callbacks (I guess I could live without them but it would be nice to use them).
2. Plot the heatmap for a single color, and then “fix” it for the remaining colors by adding some rectangle shapes on top. However, this feels hacky and it may be hard to make sure the colored rectangles align perfectly.

Any suggestions?
Thanks!

Hi @ruisilva, welcome to the forum! You could also have a given number of `go.Heatmap` cells for each day, and color them accordingly. In your example with A, B, C you would need 6 cells per day (so that you can do either 6 cells for one color, 3 + 3 or 2 + 2 +2). For more possible events `n` you would need to compute the least common multiplier (lcm, see `numpy.lcm`) of 2, 3, … `n`.

Hi @Emmanuelle,
My only problem now regards the separation of the 6x6 blocks.

It seems that `xgap` and `ygap` parameters of Heatmap separate the small individual blocks.
I’ve also tried setting a grid in the x and yaxis but it does not seem to show up:

Here is the code I’ve used to generate the example above:

``````def small_example():
import plotly.graph_objects as go
import itertools
import numpy as np

lcm = 6
# 2 x 3 list of events
nrow, ncol = 2, 3
labels = [[, [4, 2, 3], ],
[, [2, 3], ]]
data = np.array(labels)

def expand_cols(x):
return list(
itertools.chain.from_iterable(
itertools.repeat(n, lcm // len(x)) for n in x))
expander = np.vectorize(expand_cols, otypes=[np.object])
data = expander(data) # expand cols

data = np.vstack(data.tolist()) # make np array
data = data.reshape(nrow, -1)

data = np.repeat(data, lcm, axis=0) # expand rows

data = [
go.Heatmap(
z=data,
hoverinfo="text",
# xgap=1,
# ygap=1,
showscale=True),
]
layout = go.Layout(
yaxis=dict(
showline=False,
showgrid=True,
gridcolor='white',
gridwidth=2,
zeroline=False,
tickmode='array',
ticktext=['R2', 'R1'],
tickvals=np.arange(lcm / 2 - .5, nrow * lcm, lcm),
),
xaxis=dict(
showline=False,
showgrid=True,
gridcolor='black',
gridwidth=2,
zeroline=False,
tickmode='array',
ticktext=['C1', 'C2', 'C3'],
tickvals=np.arange(lcm / 2 - .5, ncol * lcm, lcm),
),
)
fig = go.Figure(data=data, layout=layout)
fig.show()

small_example()
``````

I was able to achieve the desired effect in matplotlib using `ax.grid`. Is there something similar in dash?

Thanks!