geom_tile 热图中的瓦片长度不正确

Posted

技术标签:

【中文标题】geom_tile 热图中的瓦片长度不正确【英文标题】:Tile length in geom_tile heatmap incorrect 【发布时间】:2021-03-15 17:55:37 【问题描述】:

我正在尝试使用 ggplots geom_tile 在 R 中使用热图可视化工作日和一天中的几个小时的聚合值。使用我的测试数据,该方法工作得很好,但是,当我尝试另一个测试数据集的摘录时,图块的长度突然不正确。

工作测试:

# constructing testframe
  set.seed(123)
  testframe <- cbind.data.frame(
    day = factor(sample(c("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"),100, replace = TRUE), levels = rev(c("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"))),
    hour = sample(c(0:23),100, replace = TRUE),
    year = sample(c(2018,2019,2020),100, replace = TRUE),
    value = sample(seq(-312,324,1),100, replace = TRUE)
  )
  
  # trying to set scale limits somewhat intelligently
  UpperLim <- max(abs(c(max(testframe$value),min(testframe$value))))
  LowerLim <- -UpperLim
  
  # plotting
  ggplot(testframe, aes(hour, day)) +
    geom_tile(aes(fill = value), colour = "black") +
    labs(title = "Value by Weekday and Hour",
         x = "",
         y = "") +
    scale_fill_distiller(palette = "RdYlGn", direction = 1, limits = c(LowerLim, UpperLim)) +
    scale_y_discrete(drop = FALSE) +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 90, hjust = 1),
          axis.ticks.x = element_blank(),
          legend.position = "bottom",
          legend.key.width = unit(2, "cm"),
          panel.grid = element_blank()) +
    coord_equal() +
    scale_x_continuous(breaks = seq(-0.5,23.5,1),
                       limits = c(-0.5,23.5),
                       labels = c("00:00",
                                  "01:00",
                                  "02:00",
                                  "03:00",
                                  "04:00",
                                  "05:00",
                                  "06:00",
                                  "07:00",
                                  "08:00",
                                  "09:00",
                                  "10:00",
                                  "11:00",
                                  "12:00",
                                  "13:00",
                                  "14:00",
                                  "15:00",
                                  "16:00",
                                  "17:00",
                                  "18:00",
                                  "19:00",
                                  "20:00",
                                  "21:00",
                                  "22:00",
                                  "23:00",
                                  "24:00"))

正确结果:

这正是我想要的情节。但是,当我使用另一个测试数据集的摘录尝试相同的代码时,它不会以这种方式工作:

其他测试数据集:

helperframe <- structure(list(day = structure(c(7L, 7L, 6L), .Label = c("Sunday", 
"Saturday", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday"
), class = "factor"), hour = c(12L, 23L, 0L), year = c(2018, 
2018, 2018), affect = c(0, 286.11, 44.44), PosAffect = c(0, 286.11, 
44.44), NegAffect = c(0, 0, 0)), row.names = c(NA, -3L), groups = structure(list(
    day = structure(c(6L, 7L, 7L), .Label = c("Sunday", "Saturday", 
    "Friday", "Thursday", "Wednesday", "Tuesday", "Monday"), class = "factor"), 
    hour = c(0L, 12L, 23L), .rows = structure(list(3L, 1L, 2L), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, 3L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

绘制辅助框架

  # trying to set scale limits somewhat intelligently
  UpperLim <- max(abs(c(max(helperframe$affect),min(helperframe$affect))))
  LowerLim <- -UpperLim
  
  out <- ggplot(helperframe, aes(hour, day)) +
    geom_tile(aes(fill = affect), colour = "black") +
    labs(title = "Reported Affect by Weekday and Hour",
         subtitle = paste(starttime, " - ", endtime),
         x = "",
         y = "") +
    scale_fill_distiller(palette = "RdYlGn", direction = 1, limits = c(LowerLim, UpperLim)) +
    scale_y_discrete(drop = FALSE) +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 90, hjust = 1),
          axis.ticks.x = element_blank(),
          legend.position = "bottom",
          legend.key.width = unit(2, "cm"),
          panel.grid = element_blank()) +
    coord_equal() +
    scale_x_contiunous(breaks = seq(-0.5,23.5,1),
                     limits = c(-0.5,23.5),
                     labels = c("00:00",
                                "01:00",
                                "02:00",
                                "03:00",
                                "04:00",
                                "05:00",
                                "06:00",
                                "07:00",
                                "08:00",
                                "09:00",
                                "10:00",
                                "11:00",
                                "12:00",
                                "13:00",
                                "14:00",
                                "15:00",
                                "16:00",
                                "17:00",
                                "18:00",
                                "19:00",
                                "20:00",
                                "21:00",
                                "22:00",
                                "23:00",
                                "24:00"))

这给了我一个不正确的图,其中瓦片长度不正确并且瓦片的位置与数据不匹配

当我将 scale_x_continuous 切换为 scale_x_discrete 时,我确实得到了正确的图块,但现在 x 轴消失了......

对于在不丢失 x 轴的情况下获得正确的瓷砖长度和位置有什么建议吗?

【问题讨论】:

【参考方案1】:

在您的代码上尝试这些更改:

首先,格式化x轴变量:

library(ggplot2)
#Adjust hour
helperframe$hour <- factor(helperframe$hour,
                           levels = 0:24,
                           labels = c("00:00",
                                      "01:00",
                                      "02:00",
                                      "03:00",
                                      "04:00",
                                      "05:00",
                                      "06:00",
                                      "07:00",
                                      "08:00",
                                      "09:00",
                                      "10:00",
                                      "11:00",
                                      "12:00",
                                      "13:00",
                                      "14:00",
                                      "15:00",
                                      "16:00",
                                      "17:00",
                                      "18:00",
                                      "19:00",
                                      "20:00",
                                      "21:00",
                                      "22:00",
                                      "23:00",
                                      "24:00"),
                           ordered = T)

现在,剧情:

#Code
outplot <- ggplot(helperframe, aes(hour, day)) +
  geom_tile(aes(fill = affect), colour = "black") +
  labs(title = "Reported Affect by Weekday and Hour",
       subtitle = paste('starttime', " - ", 'endtime'),
       x = "",
       y = "") +
  scale_fill_distiller(palette = "RdYlGn", direction = 1, limits = c(LowerLim, UpperLim)) +
  scale_y_discrete(drop = FALSE) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1),
        axis.ticks.x = element_blank(),
        legend.position = "bottom",
        legend.key.width = unit(2, "cm"),
        panel.grid = element_blank()) +
  coord_equal()+
  scale_x_discrete(limits = c("00:00",
                                "01:00",
                                "02:00",
                                "03:00",
                                "04:00",
                                "05:00",
                                "06:00",
                                "07:00",
                                "08:00",
                                "09:00",
                                "10:00",
                                "11:00",
                                "12:00",
                                "13:00",
                                "14:00",
                                "15:00",
                                "16:00",
                                "17:00",
                                "18:00",
                                "19:00",
                                "20:00",
                                "21:00",
                                "22:00",
                                "23:00",
                                "24:00"))

输出:

【讨论】:

以上是关于geom_tile 热图中的瓦片长度不正确的主要内容,如果未能解决你的问题,请参考以下文章

根据 geom_tile() 热图中的两列值对行重新排序

带有geom_tile的热图如何在不使用构面的情况下根据另一个因素进行划分和重新排序

更改 geom_tile() 中的中断

r中的热图足球比赛

我可以在地理地图上叠加 ggplot 热图吗?

向 ggplot geom_tile 添加多个图例