绘制时间序列数据,其中每小时变化是不同列中的值

Plot Timeseries Data where the hourly variations are values in different columns

我有一个 DataFrame,如下所示。列 0:00、1:00.. 直到 24:00 代表小时数。如何绘制所有日期的项目 'foo' 和 'bar' 的每小时变化?

Date        Item  0:00   1:00  2:00  3:00  4:00  5:00  6:00 

1/1/2022    foo   2      3    4       1      5     1.5   2.5 
1/2/2022    foo   1.5    1    3       2      2.5   6     4
1/3/2022    foo   1      2    3       1      2     5     4
1/4/2022    foo   2      1    3       4      1     2.4   3
1/1/2022    bar   3      1    0       1.5    5     1.5   2.5
1/2/2022    bar   2.5    4    3       1      2.5   0     1
1/3/2022    bar   1      2    1       1      2     1.5   4
1/4/2022    bar   2      1    3       2      1     2.5   3

我尝试了以下方法

g = sns.FacetGrid(df,row='Item',col='Date')
g.map(sns.#someplot,) # within map not sure what plot should I use and how to represent x axis as the columns

如果 Items 需要带有单独图的条形图,请使用:

df1 = df.melt(['Date','Item'])
g = sns.FacetGrid(df1, row='Item', col="Date")
g.map_dataframe(sns.barplot, x="variable", y="value")

或者如果需要在一张图中同时使用 Items,请使用:

df1 = df.melt(['Date','Item'])
g = sns.FacetGrid(df1, col="Date")
g.map_dataframe(sns.barplot, x="variable", y="value", hue="Item")

使用 R 和 ggplot2,您必须转为长格式才能绘图。

library(tidyverse)

df %>%
  pivot_longer(-c(Date, Item), names_to = "time", values_to = "value") %>%
  mutate(time = ymd_hm(paste("0000-01-01",time, sep = " "))) %>%
  ggplot(aes(x = time, y = value)) +
  geom_line(aes(colour = Date)) +
  scale_x_datetime( breaks=date_breaks("60 min"), labels = date_format("%H:%M")) +
  theme(axis.text.x=element_text(size=8, angle = 90),
        axis.text.y=element_text(size=8),
        axis.title=element_text(size=10)) +
  facet_grid(~Item, scale='free_x')

如果您希望两个系列都出现在同一个地块上,这是另一种选择。

library(tidyverse) 

df %>%
  pivot_longer(-c(Date, Item), names_to = "time", values_to = "value") %>%
  mutate(Date = as.Date(Date, "%m/%d/%Y")) %>%
  mutate(time = as.POSIXct(paste(ok$Date, ok$time), format="%Y-%m-%d %H:%M")) %>%
  ggplot(aes(x = time, y = value, colour = Item, group = Item)) +
  geom_line()

*注:由于只是数据样本,存在时间间隔,因此存在锐角。

或者如果你想把它们分开,那么你可以facet绘图(也可以使用 bar 作为另一种选择)。

df %>%
  pivot_longer(-c(Date, Item), names_to = "time", values_to = "value") %>%
  mutate(Date = as.Date(Date, "%m/%d/%Y")) %>%
  mutate(time = as.POSIXct(paste(ok$Date, ok$time), format="%Y-%m-%d %H:%M")) %>%
  ggplot(aes(x = time, y = value)) +
  geom_bar(stat = "identity", aes(colour = Item, fill = Item)) +
  facet_grid(~Item, scale='free_x')

数据

df <- structure(list(Date = c("1/1/2022", "1/2/2022", "1/3/2022", "1/4/2022", 
"1/1/2022", "1/2/2022", "1/3/2022", "1/4/2022"), Item = c("foo", 
"foo", "foo", "foo", "bar", "bar", "bar", "bar"), `0:00` = c(2, 
1.5, 1, 2, 3, 2.5, 1, 2), `1:00` = c(3L, 1L, 2L, 1L, 1L, 4L, 
2L, 1L), `2:00` = c(4L, 3L, 3L, 3L, 0L, 3L, 1L, 3L), `3:00` = c(1, 
2, 1, 4, 1.5, 1, 1, 2), `4:00` = c(5, 2.5, 2, 1, 5, 2.5, 2, 1
), `5:00` = c(1.5, 6, 5, 2.4, 1.5, 0, 1.5, 2.5), `6:00` = c(2.5, 
4, 4, 3, 2.5, 1, 4, 3)), class = "data.frame", row.names = c(NA, 
-8L))

在 R 中只需使用 matplot,无需事先进行数据整理。

par(mfrow=c(1, 2)); by(df[3:9], df$Item, \(x) matplot(t(x), type='l'))

或者,更易于发布:

par(mfrow=c(1, 2))
by(df, df$Item, \(x) {
  matplot(t(x[1:4, 3:9]), type='l', main=el(x$Item), xaxt='n', xlab='t', ylab='y')
  axis(1, axTicks(1), colnames(df)[3:9])
  legend('topleft', leg=x$Date, col=seq_len(nrow(x)), lty=seq_len(nrow(x)), 
         cex=.8, ncol=2)
  })


数据:

df <- read.table(text="
                 Date Item 0:00 1:00 2:00 3:00 4:00 5:00 6:00
1 1/1/2022  foo  2.0    3    4  1.0  5.0  1.5  2.5
2 1/2/2022  foo  1.5    1    3  2.0  2.5  6.0  4.0
3 1/3/2022  foo  1.0    2    3  1.0  2.0  5.0  4.0
4 1/4/2022  foo  2.0    1    3  4.0  1.0  2.4  3.0
5 1/1/2022  bar  3.0    1    0  1.5  5.0  1.5  2.5
6 1/2/2022  bar  2.5    4    3  1.0  2.5  0.0  1.0
7 1/3/2022  bar  1.0    2    1  1.0  2.0  1.5  4.0
8 1/4/2022  bar  2.0    1    3  2.0  1.0  2.5  3.0
           ", check.names=F)