Plot multiple days data of multiple homes in Facet form of ggplot

喜欢而已 提交于 2019-12-23 01:49:19

问题


I have hourly timeseries data of three homes(H1, H2, H3) for continuous five days created as

library(xts)
library(ggplot2)
set.seed(123)
dt <- data.frame(H1 = rnorm(24*5,200,2),H2 = rnorm(24*5,150,2),H3 = rnorm(24*5,50,2)) # hourly data of three homes for 5 days
timestamp <- seq(as.POSIXct("2016-01-01"),as.POSIXct("2016-01-05 23:59:59"), by = "hour") # create timestamp
dt$timestamp <- timestamp

Now I want to plot data homewise in facet form; accordingly I melt dataframe as

tempdf <- reshape2::melt(dt,id.vars="timestamp") # melt data for faceting
colnames(tempdf) <- c("time","var","val") # rename so as not to result in conflict with another melt inside geom_line

Within each facet (for each home), I want to see the values of all the five days in line plot form (each facet should contain 5 lines corresponding to different days). Accordingly,

ggplot(tempdf) + facet_wrap(~var) + 
  geom_line(data = function(x) {
    locdat <- xts(x$val,x$time)# create timeseries object for easy splitting
    sub <- split.xts(locdat,f="days") # split data daywise of considered home
    sub2 <- sapply(sub, function(y) return(coredata(y))) # arrange data in matrix form
    df_sub2 <- as.data.frame(sub2)
    df_sub2$timestamp <- index(sub[[1]]) # forcing same timestamp for all days [okay with me]
    df_melt <- reshape2::melt(df_sub2,id.vars="timestamp") # melt to plot inside each facet
    #return(df_melt)
    df_melt
  }, aes(x=timestamp, y=value,group=variable,color=variable),inherit.aes = FALSE)

I have forced the same timestamp for all the days of a home to make plotting simple. With above code, I get plot as

Only problem with above plot is that, It is plotting same data in all the facets. Ideally, H1 facet should contain data of home 1 only and H2 facet should contain data of home 2. I know that I am not able to pass homewise data in geom_line(), can anyone help to do in correct manner.


回答1:


I think that you may find it more efficient to modify the data outside the call to ggplot rather than inside it (allows closer inspection of what is happening at each step, at least in my opinion).

Here, I am using lubridate to generate two new columns. The first holds only the date (and not the time) to allow faceting on that. The second holds the full datetime, but I then modify the date so that they are all the same. This leaves only the times as mattering (and we can suppress the chosen date in the plot).

library(lubridate)

tempdf$day <- date(tempdf$time)
tempdf$forPlotTime <- tempdf$time

date(tempdf$forPlotTime) <-
  "2016-01-01"

Then, I can pass that modified data.frame to ggplot. You will likely want to modify colors/labels, but this should get you a pretty good start.

ggplot(tempdf
       , aes(x = forPlotTime
             , y = val
             , col = as.factor(day))) +
  geom_line() +
  facet_wrap(~var) +
  scale_x_datetime(date_breaks = "6 hours"
                   , date_labels = "%H:%M")

Generates:



来源:https://stackoverflow.com/questions/41223012/plot-multiple-days-data-of-multiple-homes-in-facet-form-of-ggplot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!