how to use black-and-white fill patterns instead of color coding on Calendar Heatmap

前端 未结 3 1055
旧巷少年郎
旧巷少年郎 2020-12-07 16:19

I\'m using Paul Bleicher\'s Calendar Heatmap to visualize some events over time and I\'m interested to add black-and-white fill patterns instead of (or on top of) the color

3条回答
  •  無奈伤痛
    2020-12-07 16:42

    You can panel.level.plot from latticeExtra to add pattern. I think the question as it is asked is a little bit specific. So I try to generalize it. The idea is to give the steps to transform a time series to a calendar heatmap: with 2 patterns (fill color and a shape). We can imagine multiple time series (Close/Open). For example, you can get something like this

    enter image description here

    or like this, using a ggplot2 theme:

    enter image description here

    The function calendarHeat , giving a single time series (dat,value) , transforms data like this :

       date.seq value dotw woty   yr month seq
    1 2012-01-01    NA    0    2 2012     1   1
    2 2012-01-02    NA    1    2 2012     1   2
    3 2012-01-03    NA    2    2 2012     1   3
    4 2012-01-04    NA    3    2 2012     1   4
    5 2012-01-05    NA    4    2 2012     1   5
    6 2012-01-06    NA    5    2 2012     1   6
    

    So I assume that I have data formated like this, otherwise, I extracted from calendarHeat the part of data transformation in a function(see this gist)

     dat <- transformdata(stock.data$Date, stock.data$by)
    

    Then the calendar is essentially a levelplot with custom sacles , custom theme and custom panel' function.

    library(latticeExtra)
    levelplot(value~woty*dotw | yr, data=dat, border = "black",
              layout = c(1, nyr%%7),
              col.regions = (calendar.pal(ncolors)),
              aspect='iso',
              between = list(x=0, y=c(1,1)),
              strip=TRUE,
              panel = function(...) {
                panel.levelplot(...)
                calendar.division(...)  
                panel.levelplot.points(...,na.rm=T,
                                       col='blue',alpha=0.5,
                                       ## you can play with cex and pch here to get the pattern you      
                                       ## like
                                       cex =dat$value/max(dat$value,na.rm=T)*3
                                       pch=ifelse(is.na(dat$value),NA,20),
                                       type = c("p"))
    
              },
              scales= scales,
              xlim =extendrange(dat$woty,f=0.01),
              ylim=extendrange(dat$dotw,f=0.1),
              cuts= ncolors - 1,
              colorkey= list(col = calendar.pal(ncolors), width = 0.6, height = 0.5),
              subscripts=TRUE,
              par.settings = calendar.theme)
    

    Where the scales are:

     scales = list(
       x = list( at= c(seq(2.9, 52, by=4.42)),
                 labels = month.abb,
                 alternating = c(1, rep(0, (nyr-1))),
                 tck=0,
                 cex =1),
       y=list(
         at = c(0, 1, 2, 3, 4, 5, 6),
         labels = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
                    "Friday", "Saturday"),
         alternating = 1,
         cex =1,
         tck=0))
    

    And the theme is setting as :

     calendar.theme <- list(
       xlab=NULL,ylab=NULL,
       strip.background = list(col = "transparent"),
       strip.border = list(col = "transparent"),
       axis.line = list(col="transparent"),
       par.strip.text=list(cex=2))
    

    The panel function uses a function caelendar.division. In fact, the division of the grid(month black countour) is very long and is done using grid package in the hard way (panel focus...). I change it a little bit, and now I call it in the lattice panel function: caelendar.division.

提交回复
热议问题