You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中绘制各列采用独立缩放尺度的热图?

Hey there! I totally get what you're aiming for—building a heatmap where each column uses its own independent color scale, so values in one column don't skew the color interpretation of another. It's easy to think mainstream R packages don't have this covered, but there are actually straightforward workarounds (and even a built-in option you might have missed!). Let's break this down with your specific matrix.

First, let's define your matrix properly so we can work with it:

# Your original matrix
mat <- structure(c(37525.6, 38150.7777777778, 54772.3, 76581.6, 89016.8888888889, 132229.2, 47912.2222222222, 57342.2, 61666.6, 2071694.44444444, 4640000, 3397239.5, 310529.6, 433809.7, 437263.8, 23828.1, 33041.3, 47197.3, 19970.4, 11566.4, 14479.1), 
                 .Dim = c(3L, 7L), 
                 .Dimnames = list(c("Nor", "Plac", "Vaso"), c("Tnf", "Il6", "IL8", "IP10", "MCP1", "GCSF", "IL10")))
Solution 1: Using ggplot2 (Flexible, Tidy Approach)

This method gives you full control over scaling and visualization, perfect if you want to customize labels, colors, or layout. We'll convert the matrix to a tidy format, scale values per column, then plot with geom_tile.

library(tidyverse)

# Convert matrix to a tidy data frame
mat_tidy <- mat %>%
  as.data.frame() %>%
  rownames_to_column(var = "Group") %>%
  pivot_longer(cols = -Group, names_to = "Cytokine", values_to = "Value")

# Scale values independently for each cytokine (column)
# Here we use z-score standardization (mean = 0, SD = 1)
mat_tidy_scaled <- mat_tidy %>%
  group_by(Cytokine) %>%
  mutate(Scaled_Value = scale(Value)[,1]) %>%
  ungroup()

# Create the heatmap
ggplot(mat_tidy_scaled, aes(x = Cytokine, y = Group, fill = Scaled_Value)) +
  geom_tile(color = "white", size = 0.5) + # Add white borders between tiles
  scale_fill_gradient2(low = "#2c7fb8", mid = "white", high = "#d95f02", midpoint = 0) +
  labs(title = "Heatmap with Independent Column Scaling",
       x = "Cytokines", y = "Sample Groups", fill = "Z-Score") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1))

If you prefer min-max scaling (values scaled to 0-1 instead of z-scores), replace the mutate line with:

mutate(Scaled_Value = (Value - min(Value)) / (max(Value) - min(Value)))
Solution 2: Using pheatmap (Quick, Built-in Options)

You might not have noticed, but pheatmap actually has a built-in parameter for column-wise scaling. If you want z-score standardization per column, just use scale = "column":

library(pheatmap)

# Built-in column-wise z-score scaling
pheatmap(mat, 
         scale = "column",
         main = "Heatmap with Column-Wise Z-Score Scaling",
         color = colorRampPalette(c("#2c7fb8", "white", "#d95f02"))(100),
         border_color = "white")

If you want min-max scaling per column (instead of z-scores), preprocess the matrix first, then pass it to pheatmap:

# Min-max scale each column independently
mat_minmax_scaled <- apply(mat, 2, function(x) (x - min(x)) / (max(x) - min(x)))

# Plot the pre-scaled matrix
pheatmap(mat_minmax_scaled,
         main = "Heatmap with Column-Wise Min-Max Scaling",
         color = colorRampPalette(c("#2c7fb8", "white", "#d95f02"))(100),
         border_color = "white")
Key Notes
  • Z-score scaling is great for showing how each value compares to the average of its column (positive = above average, negative = below average)
  • Min-max scaling is better if you want to highlight the full range of values within each column, regardless of their distribution

内容的提问来源于stack exchange,提问作者Ibetthat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:03:47