为什么coord_equal会破坏我的热图

Oli*_*ver 2 datetime r heatmap ggplot2

我正在尝试使用以下数据创建热图:

> head(myData.aggregated)
             datetime value       date                time
1 2016-03-31 14:19:00     3 2016-03-31 2016-06-11 14:19:00
2 2016-03-31 14:49:00    69 2016-03-31 2016-06-11 14:49:00
3 2016-03-31 15:49:00     5 2016-03-31 2016-06-11 15:49:00
4 2016-03-31 16:19:00     7 2016-03-31 2016-06-11 16:19:00
5 2016-03-31 17:49:00     2 2016-03-31 2016-06-11 17:49:00
6 2016-03-31 18:19:00     7 2016-03-31 2016-06-11 18:19:00

> tail(myData.aggregated)
              datetime value       date                time
90 2016-04-06 13:19:00     1 2016-04-06 2016-06-11 13:19:00
91 2016-04-06 13:49:00    25 2016-04-06 2016-06-11 13:49:00
92 2016-04-06 14:19:00     7 2016-04-06 2016-06-11 14:19:00
93 2016-04-06 14:49:00     1 2016-04-06 2016-06-11 14:49:00
94 2016-04-06 22:19:00     3 2016-04-06 2016-06-11 22:19:00
95 2016-04-06 22:49:00    14 2016-04-06 2016-06-11 22:49:00
Run Code Online (Sandbox Code Playgroud)

以下是ggplot2命令.

ggplot(myData.aggregated, aes(x = time, y = date, fill = scale(value))) + geom_tile() + coord_equal()
Run Code Online (Sandbox Code Playgroud)

一旦我添加coord_equal(),结果就是一个空白图.有人可以向我解释为什么会发生这种情况以及如何解决这个问题.我的目标是每30分钟间隔使用方形瓷砖获得热图.

更新1:

> dput(head(myData.aggregated))
structure(list(datetime = structure(c(1459426740, 1459428540, 
1459432140, 1459433940, 1459439340, 1459441140), class = c("POSIXct", 
"POSIXt"), tzone = ""), value = c(3L, 69L, 5L, 7L, 2L, 7L), date = structure(c(16891, 
16891, 16891, 16891, 16891, 16891), class = "Date"), time = structure(c(1465647540, 
1465649340, 1465652940, 1465654740, 1465660140, 1465661940), class = c("POSIXct", 
"POSIXt"), tzone = "")), .Names = c("datetime", "value", "date", 
"time"), row.names = c(NA, 6L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)

eip*_*i10 6

TL; DR: y轴跨越六个单位,x轴跨越数万个单位.当你添加时coord_equal,y轴被压扁到x轴物理长度的大约1/10,000,有效地使绘图区域消失.所述date柱(y轴)恰好是在天,time在几秒钟内柱(x轴),但都被视为由ggplot无单位的数字.你也可以在几秒钟内命名y轴,但这仍然会给你一个不良宽高比至少为6:1的情节.请参阅下面的代码和其他详细信息.


这里发生的事情:dateDate格式,因此计价天,射程6天.timePOSIXct格式,这是秒结算,有一个范围(因为我们只在一天的时间有兴趣,不论日期)的秒(达数万的,成千上万的为最多86400秒,或长度一天).

DatePOSIXct格式的基础值只是数字值,分别附加DatePOSIXct类.因此,当你添加时coord_equal,y轴上的一个单位占用与x轴上1个单位相同的物理距离,因为ggplot(显然)coord_equal根据值的数值大小计算,而不考虑它们的日期 -时间等级.但整个y轴跨越6个单位,而x轴跨越数万个单位.因此,当您需要时coord_equal,y:x纵横比会被压缩到大约1:10,000左右的数量级,使得绘图在所有实际用途中都会消失.

您可以在几秒内命名x和y轴,但即使这样,y轴将至少跨越范围(6天)的六倍作为x轴(最多一天),从而产生ay:x纵横比至少6:1 coord_equal,优于1:10,000,但仍不太实用.

这是假数据的一个例子:

# Fake data
set.seed(4959)
dat = data.frame(datetime=seq(as.POSIXct("2016-03-31"), as.POSIXct("2016-04-06"), by="hour"))
dat$value = sample(1:50, nrow(dat), replace=TRUE)

ggplot(dat, 
       aes(x = as.POSIXct(as.numeric(datetime) %% 86400, 
                          tz="UTC", origin=as.Date("2016-01-01")), 
           y = as.POSIXct(as.Date(datetime)), 
           fill = scale(value))) + 
  geom_tile() + 
  labs(y="Date", x="Time") + 
  scale_x_datetime(date_labels="%H:%m") +
  coord_equal()
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,要创建y值,我们首先转换为Dateformat,这样可以消除一天中的时间,然后转换回POSIXct将单位转换为秒,但是当天的时间等于给datetime定日期的所有值的午夜.

要创建x值,我们只需要在午夜之后的几秒钟内的时间,因此我们计算除法后的数值的剩余部分datetime86400(一天中的秒数).该tz=UTC是必要的,以获得正确的时间和origin(可以是任何日期;我们只想一天的时间)才能得到无差错运行的功能.

下面是情节看起来和没有的情况coord_equal.请注意,coord_equal对于x轴,跨越一天(从午夜到午夜)的长度与y轴上的一天相同.那是因为我们以秒为单位计算了y和x值.但是,只要y轴跨越几天并且x轴仅跨越一天,coord_equal将导致不期望的纵横比.

在此输入图像描述

下面是一个演示,如果y值以天而不是秒计算,y轴如何相对于x轴被压扁,并coord_equal指定:

ggplot(dat, 
       aes(x = as.POSIXct(as.numeric(datetime) %% 86400, 
                          tz="UTC", origin=as.Date("2016-01-01")), 
           y = as.Date(datetime), 
           fill = scale(value))) + 
  geom_tile() + 
  labs(y="Date", x="Time") + 
  scale_x_datetime(date_labels="%H:%m") + 
  coord_equal()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述