类别的二维密度图

2d density plot for categories

我正在尝试制作一个二维密度图,其中显示每个类别的密度。例如,在下图中,我们有一个每一天的密度图,所有的每日密度都被组合成彩色图。这些类型的图在大气科学和气溶胶污染研究的科学文献中很常见。

到目前为止我得到了这个

ggplot(dat, aes(y = `dN/dlogDp`, x = date)) +
  stat_density2d(geom="tile", aes(fill = ..density..), contour = FALSE) +
  scale_fill_gradient(low="blue", high="red") +
  geom_point(alpha = 0.1)   +
  theme_bw()

但我想每天都刻面,但我不知道从哪里开始。

示例数据如下:

structure(list(date = structure(c(1359244800, 1359245400, 1359246000, 
1359246600, 1359247200, 1359247800, 1359248400, 1359249000, 1359249600, 
1359250200, 1359250800, 1359251400, 1359252000, 1359252600, 1359253200, 
1359253800, 1359254400, 1359255000, 1359255600, 1359256200, 1359256800, 
1359257400, 1359258000, 1359258600, 1359259200, 1359259800, 1359260400, 
1359261000, 1359261600, 1359262200, 1359262800, 1359263400, 1359264000, 
1359264600, 1359265200, 1359265800, 1359266400, 1359267000, 1359267600, 
1359268200, 1359268800, 1359269400, 1359270000, 1359270600, 1359271200, 
1359271800, 1359272400, 1359273000, 1359273600, 1359274200, 1359274800, 
1359275400, 1359276000, 1359276600, 1359277200, 1359277800, 1359278400, 
1359279000, 1359279600, 1359280200, 1359280800, 1359281400, 1359282000, 
1359282600, 1359283200, 1359283800, 1359284400, 1359285000, 1359285600, 
1359286200, 1359286800, 1359287400, 1359288000, 1359288600, 1359289200, 
1359289800, 1359290400, 1359291000, 1359291600, 1359292200, 1359292800, 
1359293400, 1359294000, 1359294600, 1359295200, 1359295800, 1359296400, 
1359297000, 1359297600, 1359298200, 1359298800, 1359299400, 1359300000, 
1359300600, 1359301200, 1359301800, 1359302400, 1359303000, 1359303600, 
1359304200), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    `dN/dlogDp` = c(49.8, 49.275, 47.4, 47.975, 48.625, 51.725, 
    50.7, 47.55, 45.975, 45.35, 45.4, 47.75, 49.625, 48.225, 
    47.65, 47.3, 48.75, 50.075, 34.725, 42.025, 48.825, 52.25, 
    54.05, 49.15, 34.6, 34.375, 42.85, 30.325, 43.15, 36.875, 
    32.85, 36.85, 35.725, 39.8, 38.65, 40.1, 42.675, 38.5, 37.2, 
    34.425, 25.2, 14.725, 22.675, 14.875, 37.45, 46.025, 49.275, 
    35.425, 30, 38.9, 28.6, 41.675, 46.05, 48.6, 62.425, 62.65, 
    61.7, 49.5, 70.05, 71.875, 59.4, 38.525, 36.85, 25.625, 14.675, 
    14.7, 14.6, 14.725, 15.6, 15, 14.6, 14.75, 15.05, 14.975, 
    15.425, 15.1, 15.95, 14.95, 15, 14.6, 14.725, 14.85, 15.175, 
    28.95, 14.975, 14.725, 16.6, 18.925, 53.225, 60.2, 56.425, 
    54.55, 41.4, 19.025, 19.825, 31.875, 14.85, 16.375, 16.65, 
    34.325), Diameter = c(14.6, 15.1, 15.7, 16.3, 16.8, 17.5, 
    18.1, 18.8, 19.5, 20.2, 20.9, 21.7, 22.5, 23.3, 24.1, 25, 
    25.9, 26.9, 27.9, 28.9, 30, 31.1, 32.2, 33.4, 34.6, 35.9, 
    37.2, 38.5, 40, 41.4, 42.9, 44.5, 46.1, 47.8, 49.6, 51.4, 
    53.3, 55.2, 57.3, 59.4, 61.5, 63.8, 66.1, 68.5, 71, 73.7, 
    76.4, 79.1, 82, 85.1, 88.2, 91.4, 94.7, 98.2, 101.8, 105.5, 
    109.4, 113.4, 117.6, 121.9, 126.3, 131, 135.8, 140.7, 145.9, 
    151.2, 156.8, 162.5, 168.5, 174.7, 181.1, 187.7, 194.6, 201.7, 
    209.1, 216.7, 224.7, 232.9, 241.4, 250.3, 259.5, 269, 278.8, 
    289, 299.6, 310.6, 322, 333.8, 346, 358.7, 371.8, 385.4, 
    399.5, 414.2, 429.4, 445.1, 461.4, 478.3, 495.8, 514)), .Names = c("date", 
"dN/dlogDp", "Diameter"), row.names = c(NA, 100L), class = c("tbl_df", 
"tbl", "data.frame"))

UPDATE 这个问题被误导了,我现在认为使用类别与重新创建此图无关。这些其他问题与重新创建此图的任务更密切相关:

在我问了这个问题之后,我一直在更新 R 代码的要点,其中结合了这些问题的答案的详细信息,并成功地复制了这些图(要点中包含示例输出)。要点在这里:https://gist.github.com/benmarwick/9a54cbd325149a8ff405

关键步骤是去除面板中的大部分装饰,并使用 scale_*_continuous(expand = c(0,0)) 使密度图填满整个面板。以下是如何将其组合在一起的示例:

# get the day and hour to use as facet panels
dat$day <- as.Date(dat$date)
dat$hour <- as.numeric(format(dat$date, "%H"))

library(ggplot2)
library(viridis)

# theme to suppress many details
squeeze_grid_theme <- theme_bw() + theme(axis.title = element_blank(), 
                            axis.ticks = element_blank(), 
                            axis.text = element_blank(), 
                            strip.text = element_blank(), 
                            strip.background = element_blank(), 
                            panel.margin.y = unit(0, "lines"), 
                            panel.margin.x = unit(-1,"lines"),
                            panel.border = element_blank(), 
                            panel.grid = element_blank(), 
                            axis.text.x = element_text(margin=margin(0,0,0,0,"pt")),
                            axis.text.y = element_text(margin=margin(0,0,0,0,"pt")))

p <- ggplot(dat, aes(z = Diameter, y = `dN/dlogDp`, x = date)) +
  stat_density2d(geom="tile", aes(fill = ..density..), contour = FALSE) +
  scale_fill_viridis() +
  geom_point(alpha = 0.1)   +
  facet_grid(~hour) +
  scale_y_continuous(expand = c(0,0)) + 
  scale_x_datetime(expand = c(0,0)) +
  squeeze_grid_theme

p

然后我们得到一个单独的每小时密度图,像问题中的示例图一样紧紧地挤在一起。