ggplot:如何使时间序列图的 x/time-axis 只有时间分量,而不是日期?
ggplot: How to make the x/time-axis of a time-series plot only the time-component, not the date?
考虑以下示例
library(lubridate)
library(tidyverse)
library(scales)
library(ggplot2)
dataframe <- data_frame(time = c(ymd_hms('2008-01-04 00:00:00'),
ymd_hms('2008-01-04 00:01:00'),
ymd_hms('2008-01-04 00:02:00'),
ymd_hms('2008-01-04 00:03:00'),
ymd_hms('2008-01-05 00:00:00'),
ymd_hms('2008-01-06 00:01:00'),
ymd_hms('2008-01-07 00:02:00'),
ymd_hms('2008-01-08 00:03:00')),
value = c(1,2,3,4,5,6,7,8))
# A tibble: 8 × 2
time value
<dttm> <dbl>
1 2008-01-03 19:00:00 1
2 2008-01-03 19:01:00 2
3 2008-01-03 19:02:00 3
4 2008-01-03 19:03:00 4
5 2008-01-04 19:00:00 5
6 2008-01-05 19:01:00 6
7 2008-01-06 19:02:00 7
8 2008-01-07 19:03:00 8
我需要做的很简单:我需要计算样本中所有天的同一小时-分钟-秒 value
的平均值,并绘制它。
我做了以下事情:
dataframe <- dataframe %>%
mutate(hour = strftime(time, format="%H:%M:%S")) %>%
group_by(hour) %>%
summarize(mean = mean(value)) %>%
ungroup()
> dataframe
# A tibble: 4 × 2
hour mean
<chr> <dbl>
1 19:00:00 3
2 19:01:00 4
3 19:02:00 5
4 19:03:00 6
ggplot(dataframe, aes(x = hour, y = mean, group = 1)) +
geom_line(size = 2)
这种方法有两个问题
- 很明显,R并没有理解x轴是有时间意义的。这只是一个字符向量。
- 因此,我无法使用
scale_x_discrete(breaks= scales::pretty_breaks(n = 10)
有效地控制x轴。这是一个大问题,因为我的数据在一整天内以微小的频率出现。 x 轴上的标签太多了。
有人可以在这里做得更好吗?是否可以在 x 轴上保留某种时间变量,即使没有与这些时间关联的具体日期?
谢谢!
我们只需要一个 POSIX 日期时间,所有时间都具有相同的日期。日期无所谓,随便选一个:
dataframe <- dataframe %>%
mutate(hour = strftime(time, format="%H:%M:%S")) %>%
group_by(hour) %>%
summarize(mean = mean(value)) %>%
# add the date back in
mutate(x_date = ymd_hms(paste("2008-01-01", hour))) %>%
ungroup()
ggplot(dataframe, aes(x = x_date, y = mean, group = 1)) +
geom_line(size = 2)
就像 1 到 10 之间的数字默认情况下不会标记为 001、002、003 等一样,同一天的日期时间默认情况下不会标记日期和时间。可以在 scale_x_datetime
.
中修改默认值
考虑以下示例
library(lubridate)
library(tidyverse)
library(scales)
library(ggplot2)
dataframe <- data_frame(time = c(ymd_hms('2008-01-04 00:00:00'),
ymd_hms('2008-01-04 00:01:00'),
ymd_hms('2008-01-04 00:02:00'),
ymd_hms('2008-01-04 00:03:00'),
ymd_hms('2008-01-05 00:00:00'),
ymd_hms('2008-01-06 00:01:00'),
ymd_hms('2008-01-07 00:02:00'),
ymd_hms('2008-01-08 00:03:00')),
value = c(1,2,3,4,5,6,7,8))
# A tibble: 8 × 2
time value
<dttm> <dbl>
1 2008-01-03 19:00:00 1
2 2008-01-03 19:01:00 2
3 2008-01-03 19:02:00 3
4 2008-01-03 19:03:00 4
5 2008-01-04 19:00:00 5
6 2008-01-05 19:01:00 6
7 2008-01-06 19:02:00 7
8 2008-01-07 19:03:00 8
我需要做的很简单:我需要计算样本中所有天的同一小时-分钟-秒 value
的平均值,并绘制它。
我做了以下事情:
dataframe <- dataframe %>%
mutate(hour = strftime(time, format="%H:%M:%S")) %>%
group_by(hour) %>%
summarize(mean = mean(value)) %>%
ungroup()
> dataframe
# A tibble: 4 × 2
hour mean
<chr> <dbl>
1 19:00:00 3
2 19:01:00 4
3 19:02:00 5
4 19:03:00 6
ggplot(dataframe, aes(x = hour, y = mean, group = 1)) +
geom_line(size = 2)
这种方法有两个问题
- 很明显,R并没有理解x轴是有时间意义的。这只是一个字符向量。
- 因此,我无法使用
scale_x_discrete(breaks= scales::pretty_breaks(n = 10)
有效地控制x轴。这是一个大问题,因为我的数据在一整天内以微小的频率出现。 x 轴上的标签太多了。
有人可以在这里做得更好吗?是否可以在 x 轴上保留某种时间变量,即使没有与这些时间关联的具体日期?
谢谢!
我们只需要一个 POSIX 日期时间,所有时间都具有相同的日期。日期无所谓,随便选一个:
dataframe <- dataframe %>%
mutate(hour = strftime(time, format="%H:%M:%S")) %>%
group_by(hour) %>%
summarize(mean = mean(value)) %>%
# add the date back in
mutate(x_date = ymd_hms(paste("2008-01-01", hour))) %>%
ungroup()
ggplot(dataframe, aes(x = x_date, y = mean, group = 1)) +
geom_line(size = 2)
就像 1 到 10 之间的数字默认情况下不会标记为 001、002、003 等一样,同一天的日期时间默认情况下不会标记日期和时间。可以在 scale_x_datetime
.