I have a questionnaire where users answers with scores from 1 to 7 (Likert scale). The questionnaire is divided in two sections. The users belongs to two groups (X and Y), and each user may have one of two roles (A and B). I am using seaborn heatmap
on a FacetGrid
to show the results of the questionnaire.
Here is my code:
import pandas as pd
import seaborn as sns
df = pd.DataFrame(
data={
'Group': ['X', 'Y', 'Y', 'X', 'Y', 'X', 'Y', 'Y', 'X', 'X'],
'Role': ['A', 'B', 'A', 'A', 'B', 'B', 'A', 'A', 'A', 'B'],
'Question 1': [3,6,5,5,6,6,4,5,7,5],
'Question 2': [7,7,5,6,4,4,4,4,7,5],
'Question 3': [6,5,3,5,7,7,6,5,4,4],
'Question 4': [6,3,4,5,5,7,6,5,4,4]
}
)
def f(group):
gg = group[group.columns[-4:]].T.apply(lambda row : row.value_counts(), axis=1)
for score in range(1, 8):
if score not in gg:
gg[score] = 0.0
return gg
df1 = df.groupby(['Group', 'Role']) \
.apply(f) \
.fillna(0) \
.reset_index() \
.rename(columns={'level_2':'Question'})
fg = sns.FacetGrid(
data=df1,
row='Group',
col='Role'
)
def draw_heatmap(*args, **kwargs):
data = kwargs.pop('data')
d = data[['Question', 1, 2, 3, 4, 5, 6, 7]] \
.melt(id_vars='Question', var_name="Likert Score", value_name="Count") \
.pivot(index="Question", columns="Likert Score", values="Count")
d = d.div(d.sum(axis=1), axis=0).round(2)
sns.heatmap(d, **kwargs)
fg.map_dataframe(
draw_heatmap,
cbar_ax=fg.fig.add_axes([1, 0.3, .02, .4]),
cbar_kws={'label': 'Percentage of responses'},
vmin=0,
vmax=1,
cmap="Blues",
linewidths=.1
)
And this is the output:
I would like to show which section of the questionnaire the questions belong to, ideally something like the following:
I have seen this question, but I have not been able to apply the suggested solution to my case.
Any help is highly appreciated. Thank you!