r - Replicate the style of tisPlot in ggplot2 -
i want replicate style of tisplot, tis package, in ggplot2. having trouble creating line segments capping both left , right y-axes in ggplot2. have attached example code shows basic tisplot along have done match style in ggplot2. here know how solve last part of problem, namely, adding line segments @ tops of y-axes? thanks.
library(tis) library(tidyverse) library(lubridate) set.seed(5) # make example time-series data firsttis <- tis(cumsum(rnorm(120)), start = c(1996, 1), freq = 12) tisplot(firsttis) # put example times-series data dataframe df <- data_frame( date = firsttis %>% time() %>% date_decimal() %>% date(), firsttis = firsttis %>% as.numeric() ) ggplot(df) + geom_line(aes(x = date, y = firsttis)) + theme_classic() + theme( axis.ticks.length = unit(- 7, "pt"), axis.text.x = element_text(margin = margin(t = 10, b = 0, unit = "pt")), axis.text.y = element_text(margin = margin(r = 10, l = 0, unit = "pt"), color = "white"), axis.text.y.right = element_text(margin = margin(r = 0, l = 10, unit = "pt"), color = "black") ) + scale_y_continuous(sec.axis = dup_axis(name = "")) +
updated solution:
you can specify y-axis limits in coord_cartesian()
, & set multiplicative / additive expansion constants y-axis 0. segments added simulate appearance of longer ticks @ top. breaks can set dynamically using pretty()
base package, manual adjustment in n
if default settings return many / few breaks:
date.extension <- diff(range(df$date))*0.02 y.breaks <- pretty(df$firsttis, n = 4) # larger n return more breaks y.range <- range(y.breaks) > date.extension time difference of 72.46 days > y.breaks [1] -10 -5 0 5 10 > y.range [1] -10 10
plot:
p <- ggplot(df) + # add horizontal line segments aligned y-axis upper limit annotate("segment", y = max(y.range), yend = max(y.range), x = min(df$date)-date.extension, xend = min(df$date) + date.extension) + annotate("segment", y = max(y.range), yend = max(y.range), x = max(df$date)-date.extension, xend = max(df$date) + date.extension) + geom_line(aes(x = date, y = firsttis)) + theme_classic() + theme( axis.ticks.length = unit(- 7, "pt"), axis.text.x = element_text(margin = margin(t = 10, b = 0, unit = "pt")), axis.text.y = element_text(margin = margin(r = 10, l = 0, unit = "pt"), color = "white"), axis.text.y.right = element_text(margin = margin(r = 0, l = 10, unit = "pt"), color = "black") ) + scale_x_date(expand = c(0, 0)) + scale_y_continuous(name = "", breaks = y.breaks, expand = c(0, 0), # no expansion beyond specified limits sec.axis = dup_axis()) + coord_cartesian(xlim = c(min(df$date)-date.extension, max(df$date)+date.extension), ylim = y.range) p
(optional) prevent line segments @ top being clipped off:
gt <- ggplotgrob(p) gt$layout$clip[gt$layout$name=="panel"] <- "off" grid::grid.draw(gt)
note line segments coded extend 2% of total date range (~72 days in example) in either direction, min(df$date)
& max(df$date)
. if x-axis range changes drastically (e.g. 20 years 1 year), should still work.
Comments
Post a Comment