The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Getting Started with gghinton

library(gghinton)
library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.4.3

What is a Hinton diagram?

A Hinton diagram is a compact visualization of a numerical matrix. Each cell is represented by a square whose area is proportional to the magnitude of the value, so larger values are immediately distinguishable from smaller ones, something that colour shading alone (as in a heatmap) does not achieve as directly.

For signed data, the convention established by Geoffrey Hinton for visualizing neural network weights is:

For non-negative data, the grey background is omitted and all squares are drawn in black.

When to use a Hinton diagram

A Hinton diagram excels when:

Typical use cases include neural network weight matrices, correlation matrices, factor loadings from PCA or factor analysis, and transition matrices from Markov models.

Quick start

# A 10x10 signed matrix
set.seed(99)
m <- matrix(rnorm(100), nrow = 10)
rownames(m) <- paste0("r", 1:10)
colnames(m) <- paste0("c", 1:10)

df <- matrix_to_hinton(m)

ggplot(df, aes(x = col, y = row, weight = weight)) +
  geom_hinton() +
  scale_fill_hinton() +
  coord_fixed() +
  theme_hinton() +
  labs(title = "A signed Hinton diagram")

The five-function recipe is the standard gghinton workflow:

  1. matrix_to_hinton(): reshape the matrix to a tidy data frame
  2. geom_hinton(): draw the squares
  3. scale_fill_hinton(): apply the conventional white/black colour scheme
  4. coord_fixed(): ensure squares appear as squares (not rectangles)
  5. theme_hinton(): remove grid lines that would compete visually with the squares

Unsigned data

When all values are non-negative, geom_hinton() detects this automatically and omits the grey background.

m_pos <- abs(m)
df_pos <- matrix_to_hinton(m_pos)

ggplot(df_pos, aes(x = col, y = row, weight = weight)) +
  geom_hinton() +
  scale_fill_hinton() +
  coord_fixed() +
  theme_hinton() +
  labs(title = "An unsigned Hinton diagram")

Converting different data structures

as_hinton_df() provides a generic interface that dispatches on the class of its input.

# matrix
as_hinton_df(matrix(c(1, -2, 3, -4), 2, 2))
#>   row col weight
#> 1   2   1      1
#> 2   1   1     -2
#> 3   2   2      3
#> 4   1   2     -4

# base R table
t2 <- table(
  group   = c("A", "A", "B", "B"),
  outcome = c("yes", "no", "yes", "no")
)
as_hinton_df(t2)
#>   row col weight row_label col_label
#> 1   2   1      1         A        no
#> 2   1   1      1         B        no
#> 3   2   2      1         A       yes
#> 4   1   2      1         B       yes

If you already have a tidy data frame with the right column names, pass it directly:

tidy <- data.frame(row = c(1, 1, 2, 2), col = c(1, 2, 1, 2),
                   weight = c(0.5, -0.3, 0.8, -0.1))
as_hinton_df(tidy)
#>   row col weight
#> 1   1   1    0.5
#> 2   1   2   -0.3
#> 3   2   1    0.8
#> 4   2   2   -0.1

The scale_by parameter

By default, normalization is per-panel: the largest value in each facet fills its cell. When you want to compare magnitudes across facets, use scale_by = "global" so that all panels share the same scale.

set.seed(1)
df_a <- cbind(matrix_to_hinton(matrix(runif(9, -1,  1), 3, 3)),
              panel = "A (range +/-1)")
df_b <- cbind(matrix_to_hinton(matrix(runif(9, -5,  5), 3, 3)),
              panel = "B (range +/-5)")
df_ab <- rbind(df_a, df_b)

# Per-panel scaling: each panel's largest value fills its cell
ggplot(df_ab, aes(x = col, y = row, weight = weight)) +
  geom_hinton(scale_by = "panel") +
  scale_fill_hinton() +
  coord_fixed() +
  theme_hinton() +
  facet_wrap(~panel) +
  labs(title = 'scale_by = "panel" (default)')


# Global scaling: panel A appears much smaller
ggplot(df_ab, aes(x = col, y = row, weight = weight)) +
  geom_hinton(scale_by = "global") +
  scale_fill_hinton() +
  coord_fixed() +
  theme_hinton() +
  facet_wrap(~panel) +
  labs(title = 'scale_by = "global"')

Customization

Custom colours

Pass a named values vector to scale_fill_hinton() to override individual colours while keeping the defaults for the rest:

df <- matrix_to_hinton(m)

ggplot(df, aes(x = col, y = row, weight = weight)) +
  geom_hinton(background = FALSE) +
  scale_fill_hinton(values = c(positive = "darkblue", negative = "darkred")) +
  coord_fixed() +
  theme_hinton() +
  labs(title = "Custom colours")

Axis labels from matrix names

When matrix_to_hinton() detects row or column names it adds row_label and col_label columns that you can use with scale_* breaks and labels.

# m has rownames/colnames set above
df_named <- matrix_to_hinton(m)

ggplot(df_named, aes(x = col, y = row, weight = weight)) +
  geom_hinton() +
  scale_fill_hinton() +
  scale_x_continuous(
    breaks = seq_len(ncol(m)),
    labels = colnames(m)
  ) +
  scale_y_continuous(
    breaks = seq_len(nrow(m)),
    labels = rev(rownames(m))  # reversed because row 1 is at the top
  ) +
  coord_fixed() +
  theme_hinton() +
  labs(title = "Named axes")

Removing the background

Set background = FALSE to suppress the grey background even for signed data:

ggplot(df, aes(x = col, y = row, weight = weight)) +
  geom_hinton(background = FALSE) +
  scale_fill_hinton(values = c(positive = "grey70")) +
  coord_fixed() +
  theme_hinton() +
  labs(title = "Signed data without background")

Correlation matrix example

df_cor <- as_hinton_df(cor(mtcars))
vars <- colnames(mtcars)

ggplot(df_cor, aes(x = col, y = row, weight = weight)) +
  geom_hinton() +
  scale_fill_hinton() +
  scale_x_continuous(breaks = seq_along(vars), labels = vars) +
  scale_y_continuous(breaks = seq_along(vars), labels = rev(vars)) +
  coord_fixed() +
  theme_hinton() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "cor(mtcars)",
       subtitle = "White = positive, black = negative correlation")

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.