在每个单元格中构建具有自定义颜色的六角形热图

Constructing a hexagonal heat-map with custom colors in each cell

我想生成一个六边形格子热图,其中每个单元格代表一个组。同样,每个单元格都是一个六边形,具有独特的颜色(fill,由数据框中的列 color 设置)值,以及对应于连续的饱和度(alpha)值来自化学浓度数据集的小数值。

我想使用一种标准化的数据格式,这样我就可以根据包含 25 个组的标准化数据集快速构建图形。

例如,数据表如下所示:

      structure(list(group = 1:25, color = c("red", "brown1", "hotpink1", 
      "orange", "indianred1", "magenta", "darkgoldenrod1", "goldenrod1", 
      "gold", "deeppink", "yellow", "darkseagreen1", "aquamarine", 
      "plum", "mediumorchid4", "olivedrab1", "limegreen", "thistle1", 
      "violetred", "green4", "mediumseagreen", "darkviolet", "lightseagreen", 
      "dodgerblue2", "deepskyblue4"), alpha = c(NA, NA, NA, NA, NA, 
      NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
      NA, NA, NA, NA), x = c(1, 1.5, 1.5, 2, 2, 2, 2.5, 2.5, 2.5, 2.5, 
      3, 3, 3, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4.5, 4.5, 5), y = c(3, 
      3.5, 2.5, 4, 3, 2, 4.5, 3.5, 2.5, 1.5, 5, 4, 3, 2, 1, 4.5, 3.5, 
      2.5, 1.5, 4, 3, 2, 3.5, 2.5, 3)), class = "data.frame", row.names = c(NA, 
      -25L))

所有组 alpha = 1 的此类图可能如下所示:

dataset1dataset2(包括在下面)的图分别如下所示:

我想使用一些简单的东西,比如 hexbin(),但我还没有想出如何让它适用于这个应用程序。

数据集 1:

  structure(list(group = 1:25, color = c("red", "brown1", "hotpink1", 
  "orange", "indianred1", "magenta", "darkgoldenrod1", "goldenrod1", 
  "gold", "deeppink", "yellow", "darkseagreen1", "aquamarine", 
  "plum", "mediumorchid4", "olivedrab1", "limegreen", "thistle1", 
  "violetred", "green4", "mediumseagreen", "darkviolet", "lightseagreen", 
  "dodgerblue2", "deepskyblue4"), alpha = c(1, 1, 0.5, 0.5, 0.2, 
  0.2, 0, 0, 0.3, 0.1, 1, 0, 0, 0, 0.7, 0, 0, 0, 0, 0, 0, 0, 0, 
  0.5, 0.9), x = c(1, 1.5, 1.5, 2, 2, 2, 2.5, 2.5, 2.5, 2.5, 3, 
  3, 3, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4.5, 4.5, 5), y = c(3, 
  3.5, 2.5, 4, 3, 2, 4.5, 3.5, 2.5, 1.5, 5, 4, 3, 2, 1, 4.5, 3.5, 
  2.5, 1.5, 4, 3, 2, 3.5, 2.5, 3)), class = "data.frame", row.names = c(NA, 
  -25L))

数据集2:

structure(list(group = 1:25, color = c("red", "brown1", "hotpink1", 
"orange", "indianred1", "magenta", "darkgoldenrod1", "goldenrod1", 
"gold", "deeppink", "yellow", "darkseagreen1", "aquamarine", 
"plum", "mediumorchid4", "olivedrab1", "limegreen", "thistle1", 
"violetred", "green4", "mediumseagreen", "darkviolet", "lightseagreen", 
"dodgerblue2", "deepskyblue4"), alpha = c(0.3, 0.5, 0.6, 0, 0.7, 
0, 0, 0, 0, 0, 0, 0.5, 0.3, 0, 0, 0, 0, 0.6, 0.8, 0.5, 0.7, 0.5, 
0.5, 0.7, 0.5), x = c(1, 1.5, 1.5, 2, 2, 2, 2.5, 2.5, 2.5, 2.5, 
3, 3, 3, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4.5, 4.5, 5), y = c(3, 
3.5, 2.5, 4, 3, 2, 4.5, 3.5, 2.5, 1.5, 5, 4, 3, 2, 1, 4.5, 3.5, 
2.5, 1.5, 4, 3, 2, 3.5, 2.5, 3)), class = "data.frame", row.names = c(NA, 
-25L))

如果您愿意在 Python 中创建绘图,则以下方法可行:

import matplotlib.pyplot as plt
from matplotlib.patches import RegularPolygon
import numpy as np

data = {'group': np.arange(1, 26),
        'color': ["red", "brown", "hotpink", "orange", "indianred", "magenta", "darkgoldenrod", "goldenrod", "gold", "deeppink", "yellow", "darkseagreen", "aquamarine", "plum", "mediumorchid", "olivedrab", "limegreen", "thistle", "violet", "green", "mediumseagreen", "darkviolet", "lightseagreen", "dodgerblue", "deepskyblue"],
        'alpha': np.ones(25)}

fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.axis('off')

ind = 0
N = 5
for x in np.arange(1, 2*N):
    num_y = N - abs(x - N)
    for y in range(N + num_y, N - num_y, -2):
        hexagon = RegularPolygon((x, y/np.sqrt(3)), numVertices=6, radius=2 / 3, orientation=np.pi/2,
                                 alpha=data['alpha'][ind],
                                 facecolor=data['color'][ind], edgecolor='k')
        ax.add_patch(hexagon)
        ax.text(x, y/np.sqrt(3), f"Group{data['group'][ind]}", color='black', ha='center', va='center')
        ind += 1
plt.autoscale(enable=True)
plt.show()

这不完全是 hexbin 的设计用途,但它可能会给您一些有用的东西。您将需要修改您的坐标以获得所需的六边形位置(请参阅下面的数据集,基于数据集 2)。另外,六边形是旋转的。

library(hexbin)
library(ggplot2)

ggplot(df, aes(x = x, y = y, label = paste("Group", group))) + 
  geom_hex(stat = "identity", 
           color = "black", 
           fill = df$color, 
           alpha = df$alpha, 
           show.legend = F) + 
  geom_text() +
  scale_x_continuous(limits = c(0,6)) + 
  scale_y_continuous(limits = c(0,9)) +
  theme_void()

情节

或者,使用 stat_bin_hex 并指定 binwidth 您可以尝试以下操作。填充和 alpha 在这里按 y 的值排序。

ggplot(df, aes(x = x, y = y, label = paste("Group", group))) + 
  stat_bin_hex(color = "black", 
               fill = df[order(df$y), "color"], 
               alpha = df[order(df$y), "alpha"], 
               binwidth = c(1, 1), 
               show.legend = F) + 
  geom_text() +
  scale_x_continuous(limits = c(0,6)) + 
  scale_y_continuous(limits = c(0,9)) +
  theme_void()

情节

数据

df <- structure(list(group = 1:25, x = c(1, 1.5, 1.5, 2, 2, 2, 2.5, 
2.5, 2.5, 2.5, 3, 3, 3, 3, 3, 3.5, 3.5, 3.5, 3.5, 4, 4, 4, 4.5, 
4.5, 5), y = c(4.5, 5.4, 3.6, 6.25, 4.5, 2.75, 7.15, 5.4, 3.6, 
1.85, 8.05, 6.25, 4.5, 2.75, 1, 7.15, 5.4, 3.6, 1.85, 6.25, 4.5, 
2.75, 5.4, 3.6, 4.5), color = c("red", "brown1", "hotpink1", 
"orange", "indianred1", "magenta", "darkgoldenrod1", "goldenrod1", 
"gold", "deeppink", "yellow", "darkseagreen1", "aquamarine", 
"plum", "blue2", "olivedrab1", "limegreen", "thistle1", "violetred", 
"green4", "mediumseagreen", "darkviolet", "lightseagreen", "dodgerblue2", 
"deepskyblue4"), alpha = c(0.3, 0.5, 0.6, 0, 0.7, 0, 0, 0, 0, 
0, 0, 0.5, 0.3, 0, 0, 0, 0, 0.6, 0.8, 0.5, 0.7, 0.5, 0.5, 0.7, 
0.5)), row.names = c(NA, -25L), class = "data.frame")