Repository for Petra's work at ampli Jan-Feb 2019

app.R 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. library(reticulate)
  2. library(shiny)
  3. library(dplyr)
  4. library(ggplot2)
  5. library(shinycssloaders)
  6. library(TSA)
  7. theme_set(theme_bw())
  8. use_virtualenv("../venv/")
  9. p <- import("pandas")
  10. aggdf <- p$read_pickle("../data/9-clusters.agg.pkl")
  11. aggdf$cluster <- factor(aggdf$cluster)
  12. sns <- import("seaborn")
  13. models <- readRDS('../models/1kmods.rds')
  14. clusters = names(models)
  15. cbp <- as.character(p$Series(sns$color_palette("colorblind", as.integer(length(clusters)))$as_hex()))
  16. names(cbp) <- clusters
  17. minhwm <- readRDS("../models/weatherMinharmonic.rds")
  18. maxhwm <- readRDS("../models/weatherMaxharmonic.rds")
  19. monthchoices <- 1:12
  20. names(monthchoices) <- month.name
  21. weekdaychoices = 1:7
  22. names(weekdaychoices) = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
  23. ui <- navbarPage("Counties Power demand modelling", collapsible = TRUE, selected = "Prediction",
  24. tabPanel("Data and model",
  25. plotOutput("dataPlot") %>% withSpinner(type = 5),
  26. fluidRow(
  27. column(4,
  28. selectInput("selDR", "Cluster", choices = clusters, selected = clusters[1])
  29. ),
  30. column(4,
  31. dateRangeInput("dpDR", "Date range", start = min(as.Date(aggdf$read_time)),
  32. end = max(as.Date(aggdf$read_time)),
  33. min = min(as.Date(aggdf$read_time)),
  34. max = max(as.Date(aggdf$read_time)),
  35. format = "dd/mm/yyyy")
  36. ),
  37. column(4, p(paste("Point represents mean value of cluster, coloured line represents model prediction of",
  38. "mean value of cluster."))
  39. )
  40. )),
  41. tabPanel("Prediction",
  42. plotOutput("predPlot"),
  43. fluidRow(
  44. column(6,
  45. sliderInput("temprange", "Temperature range", min = 0, max = 30, value = c(10, 18), width = "100%", post = " °C",
  46. step = 0.5, dragRange = TRUE)),
  47. column(2,
  48. selectInput("predmon", "Month (approximate)", monthchoices, selected = 1, width = "100%")
  49. ),
  50. column(2,
  51. selectInput("predday", "Day of week", weekdaychoices, selected = 2, width = "100%")
  52. ),
  53. column(2,
  54. numericInput("prl", "Reference line (kwh)", value = 2, width = "100%")
  55. )
  56. ),
  57. h5("Number of ICPs of each cluster serviced by node:"),
  58. fluidRow(
  59. column(1, numericInput("c1v", "1:", value = 1, min = 0, step = 1, width = "100%"), offset = 0),
  60. column(1, numericInput("c2v", "2:", value = 0, min = 0, step = 1, width = "100%")),
  61. column(1, numericInput("c3v", "3:", value = 0, min = 0, step = 1, width = "100%")),
  62. column(1, numericInput("c4v", "4:", value = 0, min = 0, step = 1, width = "100%")),
  63. column(1, numericInput("c5v", "5:", value = 0, min = 0, step = 1, width = "100%")),
  64. column(1, numericInput("c6v", "6:", value = 0, min = 0, step = 1, width = "100%")),
  65. column(1, numericInput("c7v", "7:", value = 0, min = 0, step = 1, width = "100%")),
  66. column(1, numericInput("c8v", "8:", value = 0, min = 0, step = 1, width = "100%")),
  67. column(1, numericInput("c9v", "9:", value = 0, min = 0, step = 1, width = "100%"))
  68. )
  69. )
  70. )
  71. server <- function(input, output) {
  72. output$dataPlot <- renderPlot({
  73. clus <- input$selDR
  74. fildf <- filter(aggdf, cluster %in% clus) %>%
  75. mutate(r = resid(models[[clus]]), f = fitted(models[[clus]])) %>%
  76. filter(read_time >= as.POSIXct(input$dpDR[1], tz = "UTC"), read_time <= as.POSIXct(input$dpDR[2], tz = "UTC"))
  77. yrange = range(c(range(fildf$f), range(fildf$kwh_tot_mean)))
  78. dplot <- ggplot(fildf, aes(x = read_time, y = f, color = cluster))
  79. dplot <- dplot + geom_line(size = 2)
  80. dplot <- dplot + geom_point(aes(y = kwh_tot_mean), color = "black")
  81. dplot <- dplot + coord_cartesian(xlim = as.POSIXct(input$dpDR, tz = "UTC"),
  82. ylim = c(yrange[1] - (yrange[2] - yrange[1]) * 0.05,
  83. yrange[2] + (yrange[2] - yrange[1]) * 0.05),
  84. expand = FALSE)
  85. dplot <- dplot + scale_color_manual(values = cbp)
  86. dplot <- dplot + theme(legend.position = "none")
  87. dplot <- dplot + labs(y = "kwh", x = "Date/Time", caption = sprintf("Cluster: %s", clus))
  88. return(dplot)
  89. })
  90. prediction <- function() {
  91. numeclus <- c(input$c1v,input$c2v,input$c3v,input$c4v,input$c5v,input$c6v,input$c7v,input$c8v,input$c9v)
  92. numeclus[is.na(numeclus)] <- 0
  93. ystart <- floor((as.numeric(input$predmon) - 0.5) / 12 * 365.25 * 48)
  94. harm.y <- ts(1:48, frequency = 365.25 * 48, start = c(1, ystart)) %>% harmonic(2)
  95. harm.w <- ts(1:48, frequency = 7 * 48, start = c(1, 48 * (-1 + as.numeric(input$predday)))) %>% harmonic(3)
  96. harm.d <- ts(1:48, frequency = 48, start = c(1, 1)) %>% harmonic(3)
  97. colnames(harm.y) <- sprintf("%s.%s.%s", "year", rep(c("cos", "sin"), each = ncol(harm.y)/2), rep(1:(ncol(harm.y)/2), times = 2))
  98. colnames(harm.w) <- sprintf("%s.%s.%s", "week", rep(c("cos", "sin"), each = ncol(harm.w)/2), rep(1:(ncol(harm.w)/2), times = 2))
  99. colnames(harm.d) <- sprintf("%s.%s.%s", "day", rep(c("cos", "sin"), each = ncol(harm.d)/2), rep(1:(ncol(harm.d)/2), times = 2))
  100. qharm <- harmonic(ts(1:48, frequency = floor(365.25 * 48), start = c(1, ystart)), 2)
  101. # harnames <- paste0("yharm", colnames(qharm))
  102. qharm <- as.data.frame(qharm)
  103. # names(qharm) <- harnames
  104. wmmin <- input$temprange[1] - predict(minhwm, newdata = qharm, type = 'response')
  105. wmmax <- input$temprange[2] - predict(maxhwm, newdata = qharm, type = 'response')
  106. predinp <- data.frame(resmin = wmmin, resmax = wmmax)
  107. predinp <- cbind(predinp, harm.y, harm.w, harm.d)
  108. predvec = rep(0, 48)
  109. for (c in 1:length(clusters)) {
  110. predvec <- predvec + numeclus[c] * predict(models[[c]], newdata = predinp, type = 'response')
  111. }
  112. return(data.frame(x = 1:48, y = predvec))
  113. }
  114. output$predPlot <- renderPlot({
  115. predf <- prediction()
  116. predp <- ggplot(predf, aes(x, y)) + geom_line()
  117. predp <- predp + scale_y_continuous("Predicted kwh", limits = c(0, NA))
  118. predp <- predp + scale_x_continuous("Time", labels = function(x) {
  119. sprintf("%02d:%02d", (x %/% 2) %% 24, x %% 2 * 30)
  120. }, breaks = 0:12 * 4)
  121. if (!is.na(input$prl)) {
  122. predp <- predp + geom_hline(yintercept = input$prl, linetype = "dashed")
  123. }
  124. predp
  125. })
  126. }
  127. shinyApp(ui = ui, server = server)