Introduction
A raw cross-tabulation of two categorical variables is hard to read at a glance — the eye doesn't naturally spot which combinations are over- or under-represented in a table of counts. PlotContingencyHeatmap turns that cross-tab into a color-graded heatmap, normalizing by row, column, or the whole table so the shading reflects relative frequency, with annotated cells showing the exact percentage or count behind each color.
Teaching Note
Contingency heatmaps are essential for:
- Epidemiology: Analyzing the relationship between exposure levels and health outcomes.
- Healthcare: Visualizing patient triage categories across different hospital departments.
- Data Science: Evaluating the confusion matrix of a classification model.
- Public Health: Correlating socioeconomic status with specific health behaviors.
- Marketing: Analyzing customer segment preferences across different product lines.
- Social Science: Examining the relationship between education level and employment type.
- Operations: Monitoring the frequency of specific defect types across manufacturing shifts.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
dataframerequired | pd.DataFrame | — | The pandas DataFrame containing the categorical variables to analyze. |
categorical_column_name_1required | str | — | The name of the column representing the categorical variable for the y-axis (rows). |
categorical_column_name_2required | str | — | The name of the column representing the categorical variable for the x-axis (columns). |
normalize_by | {'columns', 'rows', 'all'} | 'columns' | Defines how to calculate percentages in the contingency table. 'columns' calculates percentages within each column, 'rows' within each row, and 'all' for the entire dataset. Defaults to 'columns'. |
color_palette | str | 'Blues' | The seaborn/matplotlib color map to use for the heatmap (e.g., 'Blues', 'viridis', 'YlGnBu'). Defaults to 'Blues'. |
show_legend | bool | False | Whether to display the color bar legend on the right side of the plot. Defaults to False. |
figure_size | tuple | (8, 6) | The dimensions of the output figure as a (width, height) tuple in inches. Defaults to (8, 6). |
data_label_format | str | '.1%' | The format string for the annotations inside the heatmap cells (e.g., '.1%' for percentages or 'd' for integers). Defaults to '.1%'. |
title_for_plot | str | None | The primary title text displayed at the top of the chart. Defaults to None. |
subtitle_for_plot | str | None | Descriptive subtitle text displayed below the main title. Defaults to None. |
caption_for_plot | str | None | Explanatory text or notes displayed at the bottom of the plot. Defaults to None. |
data_source_for_plot | str | None | Text identifying the source of the data, appended to the caption. Defaults to None. |
title_y_indent | float | 1.15 | Vertical offset for the title position relative to the axes. Defaults to 1.15. |
subtitle_y_indent | float | 1.1 | Vertical offset for the subtitle position relative to the axes. Defaults to 1.1. |
caption_y_indent | float | -0.15 | Vertical offset for the caption position relative to the axes. Defaults to -0.15. |
filepath_to_save_plot | str | None | The local path (ending in .png or .jpg) where the plot should be exported. If None, the file is not saved. Defaults to None. |
Returns
None — the function displays the plot using matplotlib and optionally saves it to disk.
Example
python
from analysistoolbox.visualizations import PlotContingencyHeatmap
import pandas as pd
# Epidemiology: correlation between vaccine type and symptom severity
vax_df = pd.DataFrame({
'Vaccine': ['Type A', 'Type B', 'Type A', 'Type B'] * 25,
'Severity': ['Mild', 'Mild', 'Severe', 'Moderate'] * 25
})
PlotContingencyHeatmap(
vax_df, 'Vaccine', 'Severity',
normalize_by="rows",
title_for_plot="Symptom Severity by Vaccine Type",
subtitle_for_plot="Row-normalized distribution of self-reported side effects"
)