Categorical vs. Categorical
Analyze two categorical variables with contingency tables, stacked and combination charts, and the chi-square test of independence with a worked example.
4 min read · Updated August 8, 2026
When both variables are categorical, bivariate analysis is built on one object: the contingency table (cross-tabulation), which counts observations for every combination of categories. From it flow the visualizations — stacked column and combination charts — and the chi-square test, the classical answer to “are these two variables associated?”
Stacked Column Chart
A stacked column chart compares the percentage that each category of one variable contributes to a total across the categories of the second variable. Each column is one category of the predictor, split into segments by the target’s categories — differences in segment heights between columns are the visual signature of an association.

Combination Chart
A combination chart uses two chart types to show different kinds of information at once. Here, bars show the distribution of one categorical variable while a line shows the percentage of a selected category of the second variable. It is the best visualization for demonstrating the predictive power of a predictor (X-axis) against a target (Y-axis): if the line is flat, the predictor tells you nothing; the more it tilts, the more the categories separate the target.

Chi-Square Test
The chi-square test determines whether two categorical variables are associated. It is based on the difference between the observed frequencies and the frequencies you would expect if the variables were independent. Under independence, the expected count for cell is the row total times the column total, divided by the grand total:
The test statistic accumulates the squared discrepancy over every cell of the contingency table:
with degrees of freedom for a table with rows and columns. The chi-square distribution converts the statistic to a probability : a probability near zero indicates dependency between the variables, while a probability near one means they are essentially independent.
To measure the strength of the dependency (the chi-square statistic grows with sample size, so it is not itself a strength measure), the legacy page uses the Tchouproff contingency coefficient:
Worked Example: Hair Color vs. Eye Color
The legacy example cross-tabulates hair color against eye color for 95 people. Expected frequencies under independence appear in parentheses:
| Eye color | Light hair | Dark hair | Row total |
|---|---|---|---|
| Black | 32 (24.1) | 12 (19.9) | 44 |
| Green/Blue | 14 (19.7) | 22 (16.3) | 36 |
| Others | 6 (8.2) | 9 (6.8) | 15 |
| Column total | 52 | 43 | 95 |
Walk one cell: the expected count for black eyes and light hair is , contributing to the statistic. Summing all six cells:
The low probability (0.005) shows a significant dependency between hair color and eye color. The Tchouproff coefficient,
indicates a moderate-strength association — real, but far from deterministic.
In Practice
pd.crosstab(df.a, df.b) builds the table and scipy.stats.chi2_contingency returns the statistic, p-value, degrees of freedom, and expected frequencies in one call. In machine learning, the same idea powers sklearn.feature_selection.chi2, which ranks categorical predictors against a categorical target, and information-gain measures in decision trees are close cousins of the dependency measured here.
Common Pitfalls
- Applying chi-square to tiny expected counts — the approximation breaks down silently.
- Reading the p-value as strength. With large , trivial associations reach ; report an effect size like or Cramér’s V alongside.
- Chi-square on raw numerical data — bin first (see Binning), and know that binning choices affect the result.
- Ignoring the table for the test. The cells with the largest gaps tell you where the association lives; read them.
- Claiming causation from an association in observational data.
Summary
Two categorical variables are analyzed through the contingency table: stacked and combination charts make the association visible, and the chi-square test measures its significance against the independence hypothesis, with coefficients like Tchouproff’s quantifying strength. The hair/eye example shows the full workflow — table, expected counts, on 2 degrees of freedom, — from raw counts to a defensible conclusion.