@pitscher

To illustrate the boolean value of each position in a dataframe column I suggest the following idea:

Define a dataframe, df, and associate a Heatmap to `z=df.values.T`

, i.e the rows in heatmap are the dataframe columns. Above this heatmap we are plotting a heatmap with the corresponding z of one row and len(df) columns, that contains the Boolean values resulted from a Boolean operation (and, or, not) between dataframe columns. The two heatmaps are represented in a subplot of two rows and 1 column:

```
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import numpy as np
def bool2string(A):
#convert a binary array into an array of strings 'True' and 'False'
S = np.empty(A.shape, dtype=object)
S[np.where(A)] = 'True'
S[np.where(A==0)] = 'False'
return S
clrs =[[0, '#0000db'], #discrete colorscale to map 0 (False) to dark blue, and 1 (True) to red
[0.5, '#0000db'],
[0.5, '#b10000'],
[1, '#b10000']]
d = {'Artist': [ 1, 0, 1, 1, 1, 0,1, 1,0,1],
'Institution': [0, 1, 0, 1,1,0,1, 1, 0, 1],
'Unicorn': [1,0,1,0,0,1,0,0,0,1]}
df = pd.DataFrame(d)
fig = make_subplots(rows=2, cols=1, shared_xaxes=True)
fig.update_layout(yaxis_domain=[0.75, 1], yaxis2_domain=[0, 0.725]);# assign a smaller yaxis domain for the second heatmap
groups = list(df.columns)
A = df.values.T
fig.add_trace(go.Heatmap(z= A, coloraxis='coloraxis', xgap=1, ygap=1, customdata = bool2string(A),
hovertemplate='%{customdata}<extra></extra>'), 2, 1)
# perform logical_and between A[0] and A[1] and convert the result to an array of ints;
# this array is then reshaped to a 2d array to be used as z in a Heatmap
and_01 = np.array(np.logical_and(A[0], A[1]), int).reshape(1,-1)
fig.add_trace(go.Heatmap(z= and_01,
coloraxis='coloraxis',
xgap=1, customdata = bool2string(and_01),
hovertemplate='%{customdata}<extra></extra>'
), 1, 1)
fig.update_layout(title_text= 'Your title', title_x=0.5,
width=799, height=400,
coloraxis=dict(colorscale=clrs, showscale=False),
yaxis2_tickvals=[0, 1,2], yaxis2_ticktext= groups, #yaxis2 is the yais of the heatap of 3 rows and 10 cols
yaxis2_autorange='reversed',
yaxis_showticklabels=False,
yaxis_title=f'{groups[0]}<br>and<br>{groups[1]}')
```

You can proceed similarly for A[0] and A[2], A[1] and A[2]

To calculate A[0] and A[1] and A[2] use chained `np.logical_and`

:

```
and_012 = np.logical_and(np.logical_and(A[0], A[1]), A[2])
and_012 = np.array(and_012, int).reshape(1,-1)
```